2010-10-08 15:14:14 +04:00
/* Industrialio buffer test code.
*
* Copyright ( c ) 2008 Jonathan Cameron
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation .
*
* This program is primarily intended as an example application .
* Reads the current buffer setup from sysfs and starts a short capture
* from the specified device , pretty printing the result after appropriate
* conversion .
*
* Command line parameters
* generic_buffer - n < device_name > - t < trigger_name >
* If trigger name is not specified the program assumes you want a dataready
* trigger associated with the device and goes looking for it .
*
*/
# include <unistd.h>
2015-02-26 11:49:24 +03:00
# include <stdlib.h>
2010-10-08 15:14:14 +04:00
# include <dirent.h>
# include <fcntl.h>
# include <stdio.h>
# include <errno.h>
# include <sys/stat.h>
# include <sys/dir.h>
# include <linux/types.h>
2011-02-11 16:09:12 +03:00
# include <string.h>
2011-05-18 17:41:19 +04:00
# include <poll.h>
2011-12-04 23:10:59 +04:00
# include <endian.h>
2012-06-26 01:12:17 +04:00
# include <getopt.h>
2012-06-26 01:12:16 +04:00
# include <inttypes.h>
2016-05-23 21:39:56 +03:00
# include <stdbool.h>
# include <signal.h>
2010-10-08 15:14:14 +04:00
# include "iio_utils.h"
2016-04-14 11:26:47 +03:00
/**
* enum autochan - state for the automatic channel enabling mechanism
*/
enum autochan {
AUTOCHANNELS_DISABLED ,
AUTOCHANNELS_ENABLED ,
AUTOCHANNELS_ACTIVE ,
} ;
2010-10-08 15:14:14 +04:00
/**
* size_from_channelarray ( ) - calculate the storage size of a scan
2012-06-26 01:12:14 +04:00
* @ channels : the channel info array
* @ num_channels : number of channels
2010-10-08 15:14:14 +04:00
*
* Has the side effect of filling the channels [ i ] . location values used
* in processing the buffer output .
* */
int size_from_channelarray ( struct iio_channel_info * channels , int num_channels )
{
int bytes = 0 ;
int i = 0 ;
2014-10-04 00:34:50 +04:00
2010-10-08 15:14:14 +04:00
while ( i < num_channels ) {
if ( bytes % channels [ i ] . bytes = = 0 )
channels [ i ] . location = bytes ;
else
2015-06-10 22:51:20 +03:00
channels [ i ] . location = bytes - bytes % channels [ i ] . bytes
+ channels [ i ] . bytes ;
2010-10-08 15:14:14 +04:00
bytes = channels [ i ] . location + channels [ i ] . bytes ;
i + + ;
}
2015-06-10 22:51:20 +03:00
2010-10-08 15:14:14 +04:00
return bytes ;
}
2015-07-03 12:57:36 +03:00
void print1byte ( uint8_t input , struct iio_channel_info * info )
{
/*
* Shift before conversion to avoid sign extension
* of left aligned data
*/
input > > = info - > shift ;
input & = info - > mask ;
if ( info - > is_signed ) {
int8_t val = ( int8_t ) ( input < < ( 8 - info - > bits_used ) ) > >
( 8 - info - > bits_used ) ;
printf ( " %05f " , ( ( float ) val + info - > offset ) * info - > scale ) ;
} else {
printf ( " %05f " , ( ( float ) input + info - > offset ) * info - > scale ) ;
}
}
2015-05-31 15:39:58 +03:00
void print2byte ( uint16_t input , struct iio_channel_info * info )
2011-05-18 17:41:19 +04:00
{
2011-12-04 23:10:59 +04:00
/* First swap if incorrect endian */
if ( info - > be )
2015-05-31 15:39:58 +03:00
input = be16toh ( input ) ;
2011-12-04 23:10:59 +04:00
else
2015-05-31 15:39:58 +03:00
input = le16toh ( input ) ;
2011-12-04 23:10:59 +04:00
2012-06-26 01:12:14 +04:00
/*
* Shift before conversion to avoid sign extension
* of left aligned data
*/
2015-02-26 12:45:26 +03:00
input > > = info - > shift ;
2015-05-31 15:39:58 +03:00
input & = info - > mask ;
2011-05-18 17:41:19 +04:00
if ( info - > is_signed ) {
2015-05-31 15:39:58 +03:00
int16_t val = ( int16_t ) ( input < < ( 16 - info - > bits_used ) ) > >
( 16 - info - > bits_used ) ;
printf ( " %05f " , ( ( float ) val + info - > offset ) * info - > scale ) ;
} else {
printf ( " %05f " , ( ( float ) input + info - > offset ) * info - > scale ) ;
}
}
2014-10-04 00:34:50 +04:00
2015-05-31 15:39:58 +03:00
void print4byte ( uint32_t input , struct iio_channel_info * info )
{
/* First swap if incorrect endian */
if ( info - > be )
input = be32toh ( input ) ;
else
input = le32toh ( input ) ;
/*
* Shift before conversion to avoid sign extension
* of left aligned data
*/
input > > = info - > shift ;
input & = info - > mask ;
if ( info - > is_signed ) {
int32_t val = ( int32_t ) ( input < < ( 32 - info - > bits_used ) ) > >
( 32 - info - > bits_used ) ;
printf ( " %05f " , ( ( float ) val + info - > offset ) * info - > scale ) ;
2011-05-18 17:41:19 +04:00
} else {
2015-05-31 15:39:58 +03:00
printf ( " %05f " , ( ( float ) input + info - > offset ) * info - > scale ) ;
}
}
2014-10-04 00:34:50 +04:00
2015-05-31 15:39:58 +03:00
void print8byte ( uint64_t input , struct iio_channel_info * info )
{
/* First swap if incorrect endian */
if ( info - > be )
input = be64toh ( input ) ;
else
input = le64toh ( input ) ;
/*
* Shift before conversion to avoid sign extension
* of left aligned data
*/
input > > = info - > shift ;
input & = info - > mask ;
if ( info - > is_signed ) {
int64_t val = ( int64_t ) ( input < < ( 64 - info - > bits_used ) ) > >
( 64 - info - > bits_used ) ;
/* special case for timestamp */
if ( info - > scale = = 1.0f & & info - > offset = = 0.0f )
printf ( " % " PRId64 " " , val ) ;
else
printf ( " %05f " ,
( ( float ) val + info - > offset ) * info - > scale ) ;
} else {
printf ( " %05f " , ( ( float ) input + info - > offset ) * info - > scale ) ;
2011-05-18 17:41:19 +04:00
}
}
2015-05-31 15:39:58 +03:00
2010-10-08 15:14:14 +04:00
/**
* process_scan ( ) - print out the values in SI units
* @ data : pointer to the start of the scan
2015-06-10 22:51:20 +03:00
* @ channels : information about the channels .
* Note : size_from_channelarray must have been called first
* to fill the location offsets .
2012-06-26 01:12:14 +04:00
* @ num_channels : number of channels
2010-10-08 15:14:14 +04:00
* */
void process_scan ( char * data ,
2012-06-26 01:12:14 +04:00
struct iio_channel_info * channels ,
2010-10-08 15:14:14 +04:00
int num_channels )
{
int k ;
2014-10-04 00:34:50 +04:00
2010-10-08 15:14:14 +04:00
for ( k = 0 ; k < num_channels ; k + + )
2012-06-26 01:12:14 +04:00
switch ( channels [ k ] . bytes ) {
2010-10-08 15:14:14 +04:00
/* only a few cases implemented so far */
2015-07-03 12:57:36 +03:00
case 1 :
print1byte ( * ( uint8_t * ) ( data + channels [ k ] . location ) ,
& channels [ k ] ) ;
break ;
2010-10-08 15:14:14 +04:00
case 2 :
2012-06-26 01:12:14 +04:00
print2byte ( * ( uint16_t * ) ( data + channels [ k ] . location ) ,
& channels [ k ] ) ;
2010-10-08 15:14:14 +04:00
break ;
2012-08-12 19:21:00 +04:00
case 4 :
2015-05-31 15:39:58 +03:00
print4byte ( * ( uint32_t * ) ( data + channels [ k ] . location ) ,
& channels [ k ] ) ;
2012-08-12 19:21:00 +04:00
break ;
2010-10-08 15:14:14 +04:00
case 8 :
2015-05-31 15:39:58 +03:00
print8byte ( * ( uint64_t * ) ( data + channels [ k ] . location ) ,
& channels [ k ] ) ;
2010-10-08 15:14:14 +04:00
break ;
default :
break ;
}
printf ( " \n " ) ;
}
2016-04-14 11:26:47 +03:00
static int enable_disable_all_channels ( char * dev_dir_name , int enable )
{
const struct dirent * ent ;
char scanelemdir [ 256 ] ;
DIR * dp ;
int ret ;
snprintf ( scanelemdir , sizeof ( scanelemdir ) ,
FORMAT_SCAN_ELEMENTS_DIR , dev_dir_name ) ;
scanelemdir [ sizeof ( scanelemdir ) - 1 ] = ' \0 ' ;
dp = opendir ( scanelemdir ) ;
if ( ! dp ) {
fprintf ( stderr , " Enabling/disabling channels: can't open %s \n " ,
scanelemdir ) ;
return - EIO ;
}
ret = - ENOENT ;
while ( ent = readdir ( dp ) , ent ) {
if ( iioutils_check_suffix ( ent - > d_name , " _en " ) ) {
printf ( " %sabling: %s \n " ,
enable ? " En " : " Dis " ,
ent - > d_name ) ;
ret = write_sysfs_int ( ent - > d_name , scanelemdir ,
enable ) ;
if ( ret < 0 )
fprintf ( stderr , " Failed to enable/disable %s \n " ,
ent - > d_name ) ;
}
}
if ( closedir ( dp ) = = - 1 ) {
perror ( " Enabling/disabling channels: "
" Failed to close directory " ) ;
return - errno ;
}
return 0 ;
}
2015-05-31 15:40:22 +03:00
void print_usage ( void )
{
2015-07-17 18:43:42 +03:00
fprintf ( stderr , " Usage: generic_buffer [options]... \n "
" Capture, convert and output data from IIO device buffer \n "
2016-04-14 11:26:47 +03:00
" -a Auto-activate all available channels \n "
2015-07-17 18:43:42 +03:00
" -c <n> Do n conversions \n "
" -e Disable wait for event (new data) \n "
" -g Use trigger-less mode \n "
" -l <n> Set buffer length to n samples \n "
2016-05-23 21:39:57 +03:00
" --device-name -n <name> \n "
" --device-num -N <num> \n "
" Set device by name or number (mandatory) \n "
2016-05-23 21:39:58 +03:00
" --trigger-name -t <name> \n "
" --trigger-num -T <num> \n "
" Set trigger by name or number \n "
2015-07-17 18:43:42 +03:00
" -w <n> Set delay between reads in us (event-less mode) \n " ) ;
2015-05-31 15:40:22 +03:00
}
2016-05-23 21:39:56 +03:00
enum autochan autochannels = AUTOCHANNELS_DISABLED ;
char * dev_dir_name = NULL ;
char * buf_dir_name = NULL ;
bool current_trigger_set = false ;
void cleanup ( void )
{
int ret ;
/* Disable trigger */
if ( dev_dir_name & & current_trigger_set ) {
/* Disconnect the trigger - just write a dummy name. */
ret = write_sysfs_string ( " trigger/current_trigger " ,
dev_dir_name , " NULL " ) ;
if ( ret < 0 )
fprintf ( stderr , " Failed to disable trigger: %s \n " ,
strerror ( - ret ) ) ;
current_trigger_set = false ;
}
/* Disable buffer */
if ( buf_dir_name ) {
ret = write_sysfs_int ( " enable " , buf_dir_name , 0 ) ;
if ( ret < 0 )
fprintf ( stderr , " Failed to disable buffer: %s \n " ,
strerror ( - ret ) ) ;
}
/* Disable channels if auto-enabled */
if ( dev_dir_name & & autochannels = = AUTOCHANNELS_ACTIVE ) {
ret = enable_disable_all_channels ( dev_dir_name , 0 ) ;
if ( ret )
fprintf ( stderr , " Failed to disable all channels \n " ) ;
autochannels = AUTOCHANNELS_DISABLED ;
}
}
void sig_handler ( int signum )
{
fprintf ( stderr , " Caught signal %d \n " , signum ) ;
cleanup ( ) ;
exit ( - signum ) ;
}
void register_cleanup ( void )
{
struct sigaction sa = { . sa_handler = sig_handler } ;
const int signums [ ] = { SIGINT , SIGTERM , SIGABRT } ;
int ret , i ;
for ( i = 0 ; i < ARRAY_SIZE ( signums ) ; + + i ) {
ret = sigaction ( signums [ i ] , & sa , NULL ) ;
if ( ret ) {
perror ( " Failed to register signal handler " ) ;
exit ( - 1 ) ;
}
}
}
2016-05-23 21:39:57 +03:00
static const struct option longopts [ ] = {
{ " device-name " , 1 , 0 , ' n ' } ,
{ " device-num " , 1 , 0 , ' N ' } ,
2016-05-23 21:39:58 +03:00
{ " trigger-name " , 1 , 0 , ' t ' } ,
{ " trigger-num " , 1 , 0 , ' T ' } ,
2016-05-23 21:39:57 +03:00
{ } ,
} ;
2010-10-08 15:14:14 +04:00
int main ( int argc , char * * argv )
{
2011-02-11 16:09:13 +03:00
unsigned long num_loops = 2 ;
unsigned long timedelay = 1000000 ;
unsigned long buf_len = 128 ;
2010-10-08 15:14:14 +04:00
int ret , c , i , j , toread ;
2016-05-23 21:39:56 +03:00
int fp = - 1 ;
2010-10-08 15:14:14 +04:00
2016-05-23 21:39:56 +03:00
int num_channels = 0 ;
2010-10-08 15:14:14 +04:00
char * trigger_name = NULL , * device_name = NULL ;
2016-05-23 21:39:56 +03:00
char * data = NULL ;
2011-04-15 21:56:00 +04:00
ssize_t read_size ;
2016-06-03 21:56:29 +03:00
int dev_num = - 1 , trig_num = - 1 ;
2016-05-23 21:39:56 +03:00
char * buffer_access = NULL ;
2010-10-08 15:14:14 +04:00
int scan_size ;
2011-02-11 16:09:12 +03:00
int noevents = 0 ;
2014-11-04 17:29:39 +03:00
int notrigger = 0 ;
2011-02-11 16:09:13 +03:00
char * dummy ;
2010-10-08 15:14:14 +04:00
2016-07-27 06:17:43 +03:00
struct iio_channel_info * channels = NULL ;
2010-10-08 15:14:14 +04:00
2016-05-23 21:39:56 +03:00
register_cleanup ( ) ;
2016-05-23 21:39:58 +03:00
while ( ( c = getopt_long ( argc , argv , " ac:egl:n:N:t:T:w: " , longopts , NULL ) ) ! = - 1 ) {
2010-10-08 15:14:14 +04:00
switch ( c ) {
2016-04-14 11:26:47 +03:00
case ' a ' :
autochannels = AUTOCHANNELS_ENABLED ;
break ;
2011-02-11 16:09:13 +03:00
case ' c ' :
2015-05-31 15:40:03 +03:00
errno = 0 ;
2011-02-11 16:09:13 +03:00
num_loops = strtoul ( optarg , & dummy , 10 ) ;
2016-05-23 21:39:56 +03:00
if ( errno ) {
ret = - errno ;
goto error ;
}
2015-06-10 22:51:20 +03:00
2011-02-11 16:09:13 +03:00
break ;
2015-05-31 15:40:22 +03:00
case ' e ' :
noevents = 1 ;
break ;
case ' g ' :
notrigger = 1 ;
2011-02-11 16:09:13 +03:00
break ;
case ' l ' :
2015-05-31 15:40:03 +03:00
errno = 0 ;
2011-02-11 16:09:13 +03:00
buf_len = strtoul ( optarg , & dummy , 10 ) ;
2016-05-23 21:39:56 +03:00
if ( errno ) {
ret = - errno ;
goto error ;
}
2015-06-10 22:51:20 +03:00
2011-02-11 16:09:13 +03:00
break ;
2015-05-31 15:40:22 +03:00
case ' n ' :
2016-05-23 21:39:57 +03:00
device_name = strdup ( optarg ) ;
break ;
case ' N ' :
errno = 0 ;
dev_num = strtoul ( optarg , & dummy , 10 ) ;
if ( errno ) {
ret = - errno ;
goto error ;
}
2015-05-31 15:40:22 +03:00
break ;
case ' t ' :
2016-05-23 21:39:56 +03:00
trigger_name = strdup ( optarg ) ;
2015-05-31 15:40:22 +03:00
break ;
2016-05-23 21:39:58 +03:00
case ' T ' :
errno = 0 ;
trig_num = strtoul ( optarg , & dummy , 10 ) ;
if ( errno )
return - errno ;
break ;
2015-05-31 15:40:22 +03:00
case ' w ' :
errno = 0 ;
timedelay = strtoul ( optarg , & dummy , 10 ) ;
2016-05-23 21:39:56 +03:00
if ( errno ) {
ret = - errno ;
goto error ;
}
2014-11-04 17:29:39 +03:00
break ;
2010-10-08 15:14:14 +04:00
case ' ? ' :
2015-05-31 15:40:22 +03:00
print_usage ( ) ;
2016-05-23 21:39:56 +03:00
ret = - 1 ;
goto error ;
2010-10-08 15:14:14 +04:00
}
}
/* Find the device requested */
2016-05-23 21:39:57 +03:00
if ( dev_num < 0 & & ! device_name ) {
fprintf ( stderr , " Device not set \n " ) ;
print_usage ( ) ;
ret = - 1 ;
goto error ;
} else if ( dev_num > = 0 & & device_name ) {
fprintf ( stderr , " Only one of --device-num or --device-name needs to be set \n " ) ;
print_usage ( ) ;
ret = - 1 ;
2016-05-23 21:39:56 +03:00
goto error ;
2016-05-23 21:39:57 +03:00
} else if ( dev_num < 0 ) {
dev_num = find_type_by_name ( device_name , " iio:device " ) ;
if ( dev_num < 0 ) {
fprintf ( stderr , " Failed to find the %s \n " , device_name ) ;
ret = dev_num ;
goto error ;
}
2010-10-08 15:14:14 +04:00
}
printf ( " iio device number being used is %d \n " , dev_num ) ;
2015-05-31 15:40:02 +03:00
ret = asprintf ( & dev_dir_name , " %siio:device%d " , iio_dir , dev_num ) ;
2016-05-23 21:39:57 +03:00
if ( ret < 0 )
return - ENOMEM ;
/* Fetch device_name if specified by number */
if ( ! device_name ) {
device_name = malloc ( IIO_MAX_NAME_LENGTH ) ;
if ( ! device_name ) {
ret = - ENOMEM ;
goto error ;
}
ret = read_sysfs_string ( " name " , dev_dir_name , device_name ) ;
if ( ret < 0 ) {
fprintf ( stderr , " Failed to read name of device %d \n " , dev_num ) ;
goto error ;
}
2016-05-23 21:39:56 +03:00
}
2014-11-04 17:29:39 +03:00
2016-05-23 21:39:58 +03:00
if ( notrigger ) {
printf ( " trigger-less mode selected \n " ) ;
2016-08-24 16:28:27 +03:00
} else if ( trig_num > = 0 ) {
2016-05-23 21:39:58 +03:00
char * trig_dev_name ;
ret = asprintf ( & trig_dev_name , " %strigger%d " , iio_dir , trig_num ) ;
if ( ret < 0 ) {
return - ENOMEM ;
}
trigger_name = malloc ( IIO_MAX_NAME_LENGTH ) ;
ret = read_sysfs_string ( " name " , trig_dev_name , trigger_name ) ;
free ( trig_dev_name ) ;
if ( ret < 0 ) {
fprintf ( stderr , " Failed to read trigger%d name from \n " , trig_num ) ;
return ret ;
}
printf ( " iio trigger number being used is %d \n " , trig_num ) ;
} else {
2015-07-13 16:15:56 +03:00
if ( ! trigger_name ) {
2014-11-04 17:29:39 +03:00
/*
* Build the trigger name . If it is device associated
* its name is < device_name > _dev [ n ] where n matches
* the device number found above .
*/
ret = asprintf ( & trigger_name ,
" %s-dev%d " , device_name , dev_num ) ;
if ( ret < 0 ) {
ret = - ENOMEM ;
2016-05-23 21:39:56 +03:00
goto error ;
2014-11-04 17:29:39 +03:00
}
2010-10-08 15:14:14 +04:00
}
2016-03-24 11:39:14 +03:00
/* Look for this "-devN" trigger */
trig_num = find_type_by_name ( trigger_name , " trigger " ) ;
if ( trig_num < 0 ) {
/* OK try the simpler "-trigger" suffix instead */
free ( trigger_name ) ;
ret = asprintf ( & trigger_name ,
" %s-trigger " , device_name ) ;
if ( ret < 0 ) {
ret = - ENOMEM ;
2016-05-23 21:39:56 +03:00
goto error ;
2016-03-24 11:39:14 +03:00
}
}
2014-11-04 17:29:39 +03:00
trig_num = find_type_by_name ( trigger_name , " trigger " ) ;
if ( trig_num < 0 ) {
2015-07-17 18:43:42 +03:00
fprintf ( stderr , " Failed to find the trigger %s \n " ,
trigger_name ) ;
2015-05-31 15:39:57 +03:00
ret = trig_num ;
2016-05-23 21:39:56 +03:00
goto error ;
2014-11-04 17:29:39 +03:00
}
2015-06-10 22:51:20 +03:00
2014-11-04 17:29:39 +03:00
printf ( " iio trigger number being used is %d \n " , trig_num ) ;
2015-06-10 22:51:20 +03:00
}
2010-10-08 15:14:14 +04:00
/*
* Parse the files in scan_elements to identify what channels are
* present
*/
2012-06-26 01:12:14 +04:00
ret = build_channel_array ( dev_dir_name , & channels , & num_channels ) ;
2010-10-08 15:14:14 +04:00
if ( ret ) {
2015-07-17 18:43:42 +03:00
fprintf ( stderr , " Problem reading scan element information \n "
" diag %s \n " , dev_dir_name ) ;
2016-05-23 21:39:56 +03:00
goto error ;
2010-10-08 15:14:14 +04:00
}
2016-04-14 11:26:47 +03:00
if ( num_channels & & autochannels = = AUTOCHANNELS_ENABLED ) {
fprintf ( stderr , " Auto-channels selected but some channels "
" are already activated in sysfs \n " ) ;
fprintf ( stderr , " Proceeding without activating any channels \n " ) ;
}
if ( ! num_channels & & autochannels = = AUTOCHANNELS_ENABLED ) {
fprintf ( stderr ,
" No channels are enabled, enabling all channels \n " ) ;
ret = enable_disable_all_channels ( dev_dir_name , 1 ) ;
if ( ret ) {
fprintf ( stderr , " Failed to enable all channels \n " ) ;
2016-05-23 21:39:56 +03:00
goto error ;
2016-04-14 11:26:47 +03:00
}
/* This flags that we need to disable the channels again */
autochannels = AUTOCHANNELS_ACTIVE ;
ret = build_channel_array ( dev_dir_name , & channels ,
& num_channels ) ;
if ( ret ) {
fprintf ( stderr , " Problem reading scan element "
" information \n "
" diag %s \n " , dev_dir_name ) ;
2016-05-23 21:39:56 +03:00
goto error ;
2016-04-14 11:26:47 +03:00
}
if ( ! num_channels ) {
fprintf ( stderr , " Still no channels after "
" auto-enabling, giving up \n " ) ;
2016-05-23 21:39:56 +03:00
goto error ;
2016-04-14 11:26:47 +03:00
}
}
if ( ! num_channels & & autochannels = = AUTOCHANNELS_DISABLED ) {
2015-08-10 11:55:08 +03:00
fprintf ( stderr ,
" No channels are enabled, we have nothing to scan. \n " ) ;
fprintf ( stderr , " Enable channels manually in "
FORMAT_SCAN_ELEMENTS_DIR
2016-04-14 11:26:47 +03:00
" /*_en or pass -a to autoenable channels and "
" try again. \n " , dev_dir_name ) ;
2015-08-10 11:55:08 +03:00
ret = - ENOENT ;
2016-05-23 21:39:56 +03:00
goto error ;
2015-08-10 11:55:08 +03:00
}
2010-10-08 15:14:14 +04:00
/*
* Construct the directory name for the associated buffer .
* As we know that the lis3l02dq has only one buffer this may
* be built rather than found .
*/
2011-08-30 15:32:47 +04:00
ret = asprintf ( & buf_dir_name ,
" %siio:device%d/buffer " , iio_dir , dev_num ) ;
2010-10-08 15:14:14 +04:00
if ( ret < 0 ) {
ret = - ENOMEM ;
2016-05-23 21:39:56 +03:00
goto error ;
2010-10-08 15:14:14 +04:00
}
2014-11-04 17:29:39 +03:00
if ( ! notrigger ) {
printf ( " %s %s \n " , dev_dir_name , trigger_name ) ;
2015-06-10 22:51:20 +03:00
/*
* Set the device trigger to be the data ready trigger found
* above
*/
2014-11-04 17:29:39 +03:00
ret = write_sysfs_string_and_verify ( " trigger/current_trigger " ,
dev_dir_name ,
trigger_name ) ;
if ( ret < 0 ) {
2015-07-17 18:43:42 +03:00
fprintf ( stderr ,
" Failed to write current_trigger file \n " ) ;
2016-05-23 21:39:56 +03:00
goto error ;
2014-11-04 17:29:39 +03:00
}
2010-10-08 15:14:14 +04:00
}
/* Setup ring buffer parameters */
ret = write_sysfs_int ( " length " , buf_dir_name , buf_len ) ;
if ( ret < 0 )
2016-05-23 21:39:56 +03:00
goto error ;
2010-10-08 15:14:14 +04:00
/* Enable the buffer */
ret = write_sysfs_int ( " enable " , buf_dir_name , 1 ) ;
2015-07-24 16:28:06 +03:00
if ( ret < 0 ) {
fprintf ( stderr ,
" Failed to enable buffer: %s \n " , strerror ( - ret ) ) ;
2016-05-23 21:39:56 +03:00
goto error ;
2015-07-24 16:28:06 +03:00
}
2015-06-10 22:51:20 +03:00
2012-06-26 01:12:14 +04:00
scan_size = size_from_channelarray ( channels , num_channels ) ;
2015-06-10 22:51:20 +03:00
data = malloc ( scan_size * buf_len ) ;
2010-10-08 15:14:14 +04:00
if ( ! data ) {
ret = - ENOMEM ;
2016-05-23 21:39:56 +03:00
goto error ;
2010-10-08 15:14:14 +04:00
}
2011-08-30 15:32:47 +04:00
ret = asprintf ( & buffer_access , " /dev/iio:device%d " , dev_num ) ;
2010-10-08 15:14:14 +04:00
if ( ret < 0 ) {
ret = - ENOMEM ;
2016-05-23 21:39:56 +03:00
goto error ;
2010-10-08 15:14:14 +04:00
}
/* Attempt to open non blocking the access dev */
fp = open ( buffer_access , O_RDONLY | O_NONBLOCK ) ;
2015-06-10 22:51:20 +03:00
if ( fp = = - 1 ) { /* TODO: If it isn't there make the node */
2010-10-08 15:14:14 +04:00
ret = - errno ;
2015-07-17 18:43:42 +03:00
fprintf ( stderr , " Failed to open %s \n " , buffer_access ) ;
2016-05-23 21:39:56 +03:00
goto error ;
2010-10-08 15:14:14 +04:00
}
for ( j = 0 ; j < num_loops ; j + + ) {
2011-02-11 16:09:12 +03:00
if ( ! noevents ) {
2011-05-18 17:41:19 +04:00
struct pollfd pfd = {
. fd = fp ,
. events = POLLIN ,
} ;
2015-05-31 15:40:04 +03:00
ret = poll ( & pfd , 1 , - 1 ) ;
if ( ret < 0 ) {
ret = - errno ;
2016-05-23 21:39:56 +03:00
goto error ;
2015-05-31 15:40:04 +03:00
} else if ( ret = = 0 ) {
continue ;
}
2011-05-18 17:41:19 +04:00
toread = buf_len ;
2011-02-11 16:09:12 +03:00
} else {
2011-02-11 16:09:13 +03:00
usleep ( timedelay ) ;
2011-02-11 16:09:12 +03:00
toread = 64 ;
2010-10-08 15:14:14 +04:00
}
2011-02-11 16:09:12 +03:00
2015-06-10 22:51:20 +03:00
read_size = read ( fp , data , toread * scan_size ) ;
2014-12-06 09:00:00 +03:00
if ( read_size < 0 ) {
2015-05-31 15:39:56 +03:00
if ( errno = = EAGAIN ) {
2015-07-17 18:43:42 +03:00
fprintf ( stderr , " nothing available \n " ) ;
2014-12-06 09:00:00 +03:00
continue ;
2015-06-10 22:51:20 +03:00
} else {
2014-12-06 09:00:00 +03:00
break ;
2015-06-10 22:51:20 +03:00
}
2010-10-08 15:14:14 +04:00
}
2015-06-10 22:51:20 +03:00
for ( i = 0 ; i < read_size / scan_size ; i + + )
process_scan ( data + scan_size * i , channels ,
2010-10-08 15:14:14 +04:00
num_channels ) ;
}
2016-05-23 21:39:56 +03:00
error :
cleanup ( ) ;
2010-10-08 15:14:14 +04:00
2016-05-23 21:39:56 +03:00
if ( fp > = 0 & & close ( fp ) = = - 1 )
2015-05-31 15:40:04 +03:00
perror ( " Failed to close buffer " ) ;
2010-10-08 15:14:14 +04:00
free ( buffer_access ) ;
2015-05-31 15:39:41 +03:00
free ( data ) ;
2010-10-08 15:14:14 +04:00
free ( buf_dir_name ) ;
2015-05-31 15:39:44 +03:00
for ( i = num_channels - 1 ; i > = 0 ; i - - ) {
free ( channels [ i ] . name ) ;
free ( channels [ i ] . generic_name ) ;
}
free ( channels ) ;
2016-05-23 21:39:56 +03:00
free ( trigger_name ) ;
2016-05-23 21:39:57 +03:00
free ( device_name ) ;
2015-05-31 15:39:42 +03:00
free ( dev_dir_name ) ;
2015-05-31 15:40:17 +03:00
2010-10-08 15:14:14 +04:00
return ret ;
}