diff options
Diffstat (limited to 'drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c')
-rw-r--r-- | drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c | 237 |
1 files changed, 152 insertions, 85 deletions
diff --git a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c index 2b5cfc5..3a58028 100644 --- a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c +++ b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c @@ -1,4 +1,4 @@ -/* Industrialio test ring buffer with a lis3l02dq acceleromter +/* Industrialio ring buffer with a lis3l02dq accelerometer * * Copyright (c) 2008 Jonathan Cameron * @@ -6,126 +6,181 @@ * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * - * Assumes suitable udev rules are used to create the dev nodes as named here. + * This program is primarily intended as an example application. */ #include <dirent.h> #include <fcntl.h> #include <stdio.h> #include <errno.h> -#include <stdint.h> -#include <sys/types.h> #include <sys/stat.h> #include <sys/dir.h> - #include <linux/types.h> -#include <dirent.h> -#include "iio_util.h" +#include "iio_utils.h" -static const char *ring_access = "/dev/iio/lis3l02dq_ring_access"; -static const char *ring_event = "/dev/iio/lis3l02dq_ring_event"; -static const char *device_name = "lis3l02dq"; -static const char *trigger_name = "lis3l02dq-dev0"; -static int NumVals = 3; -static int scan_ts = 1; -static int RingLength = 128; +const char *device_name = "lis3l02dq"; +const char *trigger_name_base = "lis3l02dq-dev"; +const int num_vals = 3; +const int scan_ts = 1; +const int buf_len = 128; +const int num_loops = 10; /* * Could get this from ring bps, but only after starting the ring - * which is a bit late for it to be useful + * which is a bit late for it to be useful. + * + * Todo: replace with much more generic version based on scan_elements + * directory. */ -int size_from_scanmode(int numVals, int timestamp) +int size_from_scanmode(int num_vals, int timestamp) { - if (numVals && timestamp) + if (num_vals && timestamp) return 16; else if (timestamp) return 8; else - return numVals*2; + return num_vals*2; } int main(int argc, char **argv) { + int ret; int i, j, k, toread; FILE *fp_ev; int fp; + + char *trigger_name, *dev_dir_name, *buf_dir_name; char *data; size_t read_size; struct iio_event_data dat; + int dev_num, trig_num; - char *BaseDirectoryName, - *TriggerDirectoryName, - *RingBufferDirectoryName; + char *buffer_access, *buffer_event; + const char *iio_dir = "/sys/bus/iio/devices/"; + int scan_size; + float gain = 1; - BaseDirectoryName = find_type_by_name(device_name, "device"); - if (BaseDirectoryName == NULL) { - printf("Failed to find the %s \n", device_name); - return -1; + + /* Find out which iio device is the accelerometer. */ + dev_num = find_type_by_name(device_name, "device"); + if (dev_num < 0) { + printf("Failed to find the %s\n", device_name); + ret = -ENODEV; + goto error_ret; + } + printf("iio device number being used is %d\n", dev_num); + asprintf(&dev_dir_name, "%sdevice%d", iio_dir, dev_num); + + /* + * Build the trigger name. + * In this case we want the lis3l02dq's data ready trigger + * for this lis3l02dq. The naming is lis3l02dq_dev[n], where + * n matches the device number found above. + */ + ret = asprintf(&trigger_name, "%s%d", trigger_name_base, dev_num); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_dev_dir_name; } - TriggerDirectoryName = find_type_by_name(trigger_name, "trigger"); - if (TriggerDirectoryName == NULL) { + + /* + * Find the trigger by name. + * This is techically unecessary here as we only need to + * refer to the trigger by name and that name is already + * known. + */ + trig_num = find_type_by_name(trigger_name, "trigger"); + if (trig_num < 0) { printf("Failed to find the %s\n", trigger_name); - return -1; + ret = -ENODEV; + goto error_free_triggername; } - RingBufferDirectoryName = find_ring_subelement(BaseDirectoryName, - "ring_buffer"); - if (RingBufferDirectoryName == NULL) { - printf("Failed to find ring buffer\n"); - return -1; + printf("iio trigger number being used is %d\n", trig_num); + + /* + * Read in the scale value - in a more generic case, first + * check for accel_scale, then the indivual channel scales + */ + ret = read_sysfs_float("accel_scale", dev_dir_name, &gain); + if (ret) + goto error_free_triggername;; + + /* + * 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. + */ + ret = asprintf(&buf_dir_name, "%sdevice%d:buffer0", iio_dir, dev_num); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_triggername; } - - if (write_sysfs_string_and_verify("trigger/current_trigger", - BaseDirectoryName, - (char *)trigger_name) < 0) { - printf("Failed to write current_trigger file \n"); - return -1; + /* Set the device trigger to be the data rdy trigger found above */ + ret = write_sysfs_string_and_verify("trigger/current_trigger", + dev_dir_name, + trigger_name); + if (ret < 0) { + printf("Failed to write current_trigger file\n"); + goto error_free_buf_dir_name; } /* Setup ring buffer parameters */ - if (write_sysfs_int("length", RingBufferDirectoryName, - RingLength) < 0) { - printf("Failed to open the ring buffer length file \n"); - return -1; - } + ret = write_sysfs_int("length", buf_dir_name, buf_len); + if (ret < 0) + goto error_free_buf_dir_name; - /* Enable the ring buffer */ - if (write_sysfs_int("ring_enable", RingBufferDirectoryName, 1) < 0) { - printf("Failed to open the ring buffer control file \n"); - return -1; - }; + /* Enable the buffer */ + ret = write_sysfs_int("ring_enable", buf_dir_name, 1); + if (ret < 0) + goto error_free_buf_dir_name; - data = malloc(size_from_scanmode(NumVals, scan_ts)*RingLength); + data = malloc(size_from_scanmode(num_vals, scan_ts)*buf_len); if (!data) { - printf("Could not allocate space for usespace data store\n"); - return -1; + ret = -ENOMEM; + goto error_free_buf_dir_name; + } + + ret = asprintf(&buffer_access, + "/dev/device%d:buffer0:access0", + dev_num); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_data; } + ret = asprintf(&buffer_event, "/dev/device%d:buffer0:event0", dev_num); + if (ret < 0) { + ret = -ENOMEM; + goto error_free_data; + } /* Attempt to open non blocking the access dev */ - fp = open(ring_access, O_RDONLY | O_NONBLOCK); + fp = open(buffer_access, O_RDONLY | O_NONBLOCK); if (fp == -1) { /*If it isn't there make the node */ - printf("Failed to open %s\n", ring_access); - return -1; + printf("Failed to open %s\n", buffer_access); + ret = -errno; + goto error_free_buffer_event; } /* Attempt to open the event access dev (blocking this time) */ - fp_ev = fopen(ring_event, "rb"); + fp_ev = fopen(buffer_event, "rb"); if (fp_ev == NULL) { - printf("Failed to open %s\n", ring_event); - return -1; + printf("Failed to open %s\n", buffer_event); + ret = -errno; + goto error_close_buffer_access; } /* Wait for events 10 times */ - for (j = 0; j < 10; j++) { + for (j = 0; j < num_loops; j++) { read_size = fread(&dat, 1, sizeof(struct iio_event_data), fp_ev); switch (dat.id) { case IIO_EVENT_CODE_RING_100_FULL: - toread = RingLength; + toread = buf_len; break; case IIO_EVENT_CODE_RING_75_FULL: - toread = RingLength*3/4; + toread = buf_len*3/4; break; case IIO_EVENT_CODE_RING_50_FULL: - toread = RingLength/2; + toread = buf_len/2; break; default: printf("Unexpecteded event code\n"); @@ -133,39 +188,51 @@ int main(int argc, char **argv) } read_size = read(fp, data, - toread*size_from_scanmode(NumVals, scan_ts)); + toread*size_from_scanmode(num_vals, scan_ts)); if (read_size == -EAGAIN) { - printf("nothing available \n"); + printf("nothing available\n"); continue; } - - for (i = 0; - i < read_size/size_from_scanmode(NumVals, scan_ts); - i++) { - for (k = 0; k < NumVals; k++) { - __s16 val = *(__s16 *)(&data[i*size_from_scanmode(NumVals, scan_ts) + scan_size = size_from_scanmode(num_vals, scan_ts); + for (i = 0; i < read_size/scan_size; i++) { + for (k = 0; k < num_vals; k++) { + __s16 val = *(__s16 *)(&data[i*scan_size + (k)*2]); - printf("%05d ", val); + printf("%05f ", (float)val*gain); } printf(" %lld\n", - *(__s64 *)(&data[(i+1)*size_from_scanmode(NumVals, scan_ts) + *(__s64 *)(&data[(i + 1) + *size_from_scanmode(num_vals, + scan_ts) - sizeof(__s64)])); } } /* Stop the ring buffer */ - if (write_sysfs_int("ring_enable", RingBufferDirectoryName, 0) < 0) { - printf("Failed to open the ring buffer control file \n"); - return -1; - }; - - /* Disconnect from the trigger - writing something that doesn't exist.*/ - write_sysfs_string_and_verify("trigger/current_trigger", - BaseDirectoryName, "NULL"); - free(BaseDirectoryName); - free(TriggerDirectoryName); - free(RingBufferDirectoryName); + ret = write_sysfs_int("ring_enable", buf_dir_name, 0); + if (ret < 0) + goto error_close_buffer_event; + + /* Disconnect from the trigger - just write a dummy name.*/ + write_sysfs_string("trigger/current_trigger", + dev_dir_name, "NULL"); + +error_close_buffer_event: + fclose(fp_ev); +error_close_buffer_access: + close(fp); +error_free_data: free(data); - - return 0; +error_free_buffer_access: + free(buffer_access); +error_free_buffer_event: + free(buffer_event); +error_free_buf_dir_name: + free(buf_dir_name); +error_free_triggername: + free(trigger_name); +error_free_dev_dir_name: + free(dev_dir_name); +error_ret: + return ret; } |