/* Industrialio test ring buffer with a lis3l02dq acceleromter * * 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. * * Assumes suitable udev rules are used to create the dev nodes as named here. */ #include #include #include #include #include #include #include #include #include #include #include "iio_util.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; /* * Could get this from ring bps, but only after starting the ring * which is a bit late for it to be useful */ int size_from_scanmode(int numVals, int timestamp) { if (numVals && timestamp) return 16; else if (timestamp) return 8; else return numVals*2; } int main(int argc, char **argv) { int i, j, k, toread; FILE *fp_ev; int fp; char *data; size_t read_size; struct iio_event_data dat; char *BaseDirectoryName, *TriggerDirectoryName, *RingBufferDirectoryName; BaseDirectoryName = find_type_by_name(device_name, "device"); if (BaseDirectoryName == NULL) { printf("Failed to find the %s \n", device_name); return -1; } TriggerDirectoryName = find_type_by_name(trigger_name, "trigger"); if (TriggerDirectoryName == NULL) { printf("Failed to find the %s\n", trigger_name); return -1; } RingBufferDirectoryName = find_ring_subelement(BaseDirectoryName, "ring_buffer"); if (RingBufferDirectoryName == NULL) { printf("Failed to find ring buffer\n"); return -1; } if (write_sysfs_string_and_verify("trigger/current_trigger", BaseDirectoryName, (char *)trigger_name) < 0) { printf("Failed to write current_trigger file \n"); return -1; } /* Setup ring buffer parameters */ if (write_sysfs_int("length", RingBufferDirectoryName, RingLength) < 0) { printf("Failed to open the ring buffer length file \n"); return -1; } /* 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; }; data = malloc(size_from_scanmode(NumVals, scan_ts)*RingLength); if (!data) { printf("Could not allocate space for usespace data store\n"); return -1; } /* Attempt to open non blocking the access dev */ fp = open(ring_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; } /* Attempt to open the event access dev (blocking this time) */ fp_ev = fopen(ring_event, "rb"); if (fp_ev == NULL) { printf("Failed to open %s\n", ring_event); return -1; } /* Wait for events 10 times */ for (j = 0; j < 10; 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; break; case IIO_EVENT_CODE_RING_75_FULL: toread = RingLength*3/4; break; case IIO_EVENT_CODE_RING_50_FULL: toread = RingLength/2; break; default: printf("Unexpecteded event code\n"); continue; } read_size = read(fp, data, toread*size_from_scanmode(NumVals, scan_ts)); if (read_size == -EAGAIN) { 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) + (k)*2]); printf("%05d ", val); } printf(" %lld\n", *(__s64 *)(&data[(i+1)*size_from_scanmode(NumVals, 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); free(data); return 0; }