^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Industrialio buffer test code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2008 Jonathan Cameron
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This program is primarily intended as an example application.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Reads the current buffer setup from sysfs and starts a short capture
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * from the specified device, pretty printing the result after appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * conversion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Command line parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * generic_buffer -n <device_name> -t <trigger_name>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * If trigger name is not specified the program assumes you want a dataready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * trigger associated with the device and goes looking for it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <dirent.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <sys/dir.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <endian.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <getopt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <stdbool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "iio_utils.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * enum autochan - state for the automatic channel enabling mechanism
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) enum autochan {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) AUTOCHANNELS_DISABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) AUTOCHANNELS_ENABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) AUTOCHANNELS_ACTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * size_from_channelarray() - calculate the storage size of a scan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @channels: the channel info array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @num_channels: number of channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Has the side effect of filling the channels[i].location values used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * in processing the buffer output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) while (i < num_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (bytes % channels[i].bytes == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) channels[i].location = bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) channels[i].location = bytes - bytes % channels[i].bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) + channels[i].bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) bytes = channels[i].location + channels[i].bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) void print1byte(uint8_t input, struct iio_channel_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Shift before conversion to avoid sign extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * of left aligned data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) input >>= info->shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) input &= info->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (info->is_signed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int8_t val = (int8_t)(input << (8 - info->bits_used)) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) (8 - info->bits_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) printf("%05f ", ((float)val + info->offset) * info->scale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) printf("%05f ", ((float)input + info->offset) * info->scale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) void print2byte(uint16_t input, struct iio_channel_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* First swap if incorrect endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (info->be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) input = be16toh(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) input = le16toh(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Shift before conversion to avoid sign extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * of left aligned data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) input >>= info->shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) input &= info->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (info->is_signed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int16_t val = (int16_t)(input << (16 - info->bits_used)) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) (16 - info->bits_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) printf("%05f ", ((float)val + info->offset) * info->scale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) printf("%05f ", ((float)input + info->offset) * info->scale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) void print4byte(uint32_t input, struct iio_channel_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* First swap if incorrect endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (info->be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) input = be32toh(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) input = le32toh(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * Shift before conversion to avoid sign extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * of left aligned data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) input >>= info->shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) input &= info->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (info->is_signed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int32_t val = (int32_t)(input << (32 - info->bits_used)) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) (32 - info->bits_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) printf("%05f ", ((float)val + info->offset) * info->scale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) printf("%05f ", ((float)input + info->offset) * info->scale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) void print8byte(uint64_t input, struct iio_channel_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* First swap if incorrect endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (info->be)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) input = be64toh(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) input = le64toh(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * Shift before conversion to avoid sign extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * of left aligned data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) input >>= info->shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) input &= info->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (info->is_signed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int64_t val = (int64_t)(input << (64 - info->bits_used)) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) (64 - info->bits_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* special case for timestamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (info->scale == 1.0f && info->offset == 0.0f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) printf("%" PRId64 " ", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) printf("%05f ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ((float)val + info->offset) * info->scale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) printf("%05f ", ((float)input + info->offset) * info->scale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * process_scan() - print out the values in SI units
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * @data: pointer to the start of the scan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * @channels: information about the channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * Note: size_from_channelarray must have been called first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * to fill the location offsets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * @num_channels: number of channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) void process_scan(char *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct iio_channel_info *channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int num_channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) for (k = 0; k < num_channels; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) switch (channels[k].bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* only a few cases implemented so far */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) print1byte(*(uint8_t *)(data + channels[k].location),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) &channels[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) print2byte(*(uint16_t *)(data + channels[k].location),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) &channels[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) print4byte(*(uint32_t *)(data + channels[k].location),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) &channels[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) print8byte(*(uint64_t *)(data + channels[k].location),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) &channels[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int enable_disable_all_channels(char *dev_dir_name, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) const struct dirent *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) char scanelemdir[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) DIR *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) snprintf(scanelemdir, sizeof(scanelemdir),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) FORMAT_SCAN_ELEMENTS_DIR, dev_dir_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) scanelemdir[sizeof(scanelemdir)-1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) dp = opendir(scanelemdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (!dp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) fprintf(stderr, "Enabling/disabling channels: can't open %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) scanelemdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) while (ent = readdir(dp), ent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (iioutils_check_suffix(ent->d_name, "_en")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) printf("%sabling: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) enable ? "En" : "Dis",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = write_sysfs_int(ent->d_name, scanelemdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) fprintf(stderr, "Failed to enable/disable %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ent->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (closedir(dp) == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) perror("Enabling/disabling channels: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) "Failed to close directory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) void print_usage(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) fprintf(stderr, "Usage: generic_buffer [options]...\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) "Capture, convert and output data from IIO device buffer\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) " -a Auto-activate all available channels\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) " -A Force-activate ALL channels\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) " -c <n> Do n conversions, or loop forever if n < 0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) " -e Disable wait for event (new data)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) " -g Use trigger-less mode\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) " -l <n> Set buffer length to n samples\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) " --device-name -n <name>\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) " --device-num -N <num>\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) " Set device by name or number (mandatory)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) " --trigger-name -t <name>\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) " --trigger-num -T <num>\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) " Set trigger by name or number\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) " -w <n> Set delay between reads in us (event-less mode)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) enum autochan autochannels = AUTOCHANNELS_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) char *dev_dir_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) char *buf_dir_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) bool current_trigger_set = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) void cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* Disable trigger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (dev_dir_name && current_trigger_set) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* Disconnect the trigger - just write a dummy name. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ret = write_sysfs_string("trigger/current_trigger",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) dev_dir_name, "NULL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) fprintf(stderr, "Failed to disable trigger: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) strerror(-ret));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) current_trigger_set = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* Disable buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (buf_dir_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) ret = write_sysfs_int("enable", buf_dir_name, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) fprintf(stderr, "Failed to disable buffer: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) strerror(-ret));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* Disable channels if auto-enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (dev_dir_name && autochannels == AUTOCHANNELS_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ret = enable_disable_all_channels(dev_dir_name, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) fprintf(stderr, "Failed to disable all channels\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) autochannels = AUTOCHANNELS_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) void sig_handler(int signum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) fprintf(stderr, "Caught signal %d\n", signum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) exit(-signum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) void register_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct sigaction sa = { .sa_handler = sig_handler };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) const int signums[] = { SIGINT, SIGTERM, SIGABRT };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) for (i = 0; i < ARRAY_SIZE(signums); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ret = sigaction(signums[i], &sa, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) perror("Failed to register signal handler");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) exit(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static const struct option longopts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) { "device-name", 1, 0, 'n' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) { "device-num", 1, 0, 'N' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) { "trigger-name", 1, 0, 't' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) { "trigger-num", 1, 0, 'T' },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int main(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) long long num_loops = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) unsigned long timedelay = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) unsigned long buf_len = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ssize_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsigned long long j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) unsigned long toread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int ret, c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int fp = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) int num_channels = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) char *trigger_name = NULL, *device_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) char *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ssize_t read_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) int dev_num = -1, trig_num = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) char *buffer_access = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int scan_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int noevents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int notrigger = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) char *dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) bool force_autochannels = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct iio_channel_info *channels = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) register_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) while ((c = getopt_long(argc, argv, "aAc:egl:n:N:t:T:w:?", longopts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) NULL)) != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) switch (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case 'a':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) autochannels = AUTOCHANNELS_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case 'A':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) autochannels = AUTOCHANNELS_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) force_autochannels = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case 'c':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) num_loops = strtoll(optarg, &dummy, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (errno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) case 'e':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) noevents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) case 'g':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) notrigger = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) buf_len = strtoul(optarg, &dummy, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (errno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) device_name = strdup(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) case 'N':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) dev_num = strtoul(optarg, &dummy, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (errno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) case 't':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) trigger_name = strdup(optarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) case 'T':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) trig_num = strtoul(optarg, &dummy, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (errno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) case 'w':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) timedelay = strtoul(optarg, &dummy, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (errno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) print_usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* Find the device requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (dev_num < 0 && !device_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) fprintf(stderr, "Device not set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) print_usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) } else if (dev_num >= 0 && device_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) fprintf(stderr, "Only one of --device-num or --device-name needs to be set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) print_usage();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) } else if (dev_num < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) dev_num = find_type_by_name(device_name, "iio:device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (dev_num < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) fprintf(stderr, "Failed to find the %s\n", device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = dev_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) printf("iio device number being used is %d\n", dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ret = asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* Fetch device_name if specified by number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (!device_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) device_name = malloc(IIO_MAX_NAME_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (!device_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ret = read_sysfs_string("name", dev_dir_name, device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) fprintf(stderr, "Failed to read name of device %d\n", dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (notrigger) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) printf("trigger-less mode selected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) } else if (trig_num >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) char *trig_dev_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ret = asprintf(&trig_dev_name, "%strigger%d", iio_dir, trig_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) trigger_name = malloc(IIO_MAX_NAME_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ret = read_sysfs_string("name", trig_dev_name, trigger_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) free(trig_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) fprintf(stderr, "Failed to read trigger%d name from\n", trig_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) printf("iio trigger number being used is %d\n", trig_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (!trigger_name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * Build the trigger name. If it is device associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * its name is <device_name>_dev[n] where n matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * the device number found above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ret = asprintf(&trigger_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) "%s-dev%d", device_name, dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /* Look for this "-devN" trigger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) trig_num = find_type_by_name(trigger_name, "trigger");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (trig_num < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /* OK try the simpler "-trigger" suffix instead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) free(trigger_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ret = asprintf(&trigger_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) "%s-trigger", device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) trig_num = find_type_by_name(trigger_name, "trigger");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (trig_num < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) fprintf(stderr, "Failed to find the trigger %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) trigger_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ret = trig_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) printf("iio trigger number being used is %d\n", trig_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * Parse the files in scan_elements to identify what channels are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ret = build_channel_array(dev_dir_name, &channels, &num_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) fprintf(stderr, "Problem reading scan element information\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) "diag %s\n", dev_dir_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (num_channels && autochannels == AUTOCHANNELS_ENABLED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) !force_autochannels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) fprintf(stderr, "Auto-channels selected but some channels "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) "are already activated in sysfs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) fprintf(stderr, "Proceeding without activating any channels\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if ((!num_channels && autochannels == AUTOCHANNELS_ENABLED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) (autochannels == AUTOCHANNELS_ENABLED && force_autochannels)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) fprintf(stderr, "Enabling all channels\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ret = enable_disable_all_channels(dev_dir_name, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) fprintf(stderr, "Failed to enable all channels\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /* This flags that we need to disable the channels again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) autochannels = AUTOCHANNELS_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) ret = build_channel_array(dev_dir_name, &channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) &num_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) fprintf(stderr, "Problem reading scan element "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) "information\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) "diag %s\n", dev_dir_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (!num_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) fprintf(stderr, "Still no channels after "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) "auto-enabling, giving up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (!num_channels && autochannels == AUTOCHANNELS_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) "No channels are enabled, we have nothing to scan.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) fprintf(stderr, "Enable channels manually in "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) FORMAT_SCAN_ELEMENTS_DIR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) "/*_en or pass -a to autoenable channels and "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) "try again.\n", dev_dir_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * Construct the directory name for the associated buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * As we know that the lis3l02dq has only one buffer this may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * be built rather than found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ret = asprintf(&buf_dir_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) "%siio:device%d/buffer", iio_dir, dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (!notrigger) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) printf("%s %s\n", dev_dir_name, trigger_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * Set the device trigger to be the data ready trigger found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ret = write_sysfs_string_and_verify("trigger/current_trigger",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) dev_dir_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) trigger_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) "Failed to write current_trigger file\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /* Setup ring buffer parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ret = write_sysfs_int("length", buf_dir_name, buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* Enable the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ret = write_sysfs_int("enable", buf_dir_name, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) "Failed to enable buffer: %s\n", strerror(-ret));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) scan_size = size_from_channelarray(channels, num_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) data = malloc(scan_size * buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (!data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /* Attempt to open non blocking the access dev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (fp == -1) { /* TODO: If it isn't there make the node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) fprintf(stderr, "Failed to open %s\n", buffer_access);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) for (j = 0; j < num_loops || num_loops < 0; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (!noevents) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct pollfd pfd = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .fd = fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) .events = POLLIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) ret = poll(&pfd, 1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) ret = -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) } else if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) toread = buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) usleep(timedelay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) toread = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) read_size = read(fp, data, toread * scan_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (read_size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (errno == EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) fprintf(stderr, "nothing available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) for (i = 0; i < read_size / scan_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) process_scan(data + scan_size * i, channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) num_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (fp >= 0 && close(fp) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) perror("Failed to close buffer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) free(buffer_access);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) free(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) free(buf_dir_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) for (i = num_channels - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) free(channels[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) free(channels[i].generic_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) free(channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) free(trigger_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) free(device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) free(dev_dir_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }