blob: 2d6dae0f1cf3cf71885983001c8710bb9af2faaf [file] [log] [blame]
Paul Cercueila689cd92014-03-20 16:37:25 +01001#include "iio-private.h"
2
3struct callback_wrapper_data {
4 ssize_t (*callback)(const struct iio_channel *, void *, size_t, void *);
5 void *data;
6 uint32_t *mask;
7};
8
9struct iio_buffer * iio_device_create_buffer(const struct iio_device *dev,
Paul Cercueilf88f8852014-04-01 11:50:59 +020010 size_t samples_count)
Paul Cercueila689cd92014-03-20 16:37:25 +010011{
Paul Cercueilde5a3472014-04-01 14:09:56 +020012 struct iio_buffer *buf;
13 unsigned int sample_size = iio_device_get_sample_size(dev);
14 if (!sample_size)
15 return NULL;
16
17 buf = malloc(sizeof(*buf));
Paul Cercueila689cd92014-03-20 16:37:25 +010018 if (!buf)
19 return NULL;
20
21 buf->data_length = 0;
Paul Cercueilde5a3472014-04-01 14:09:56 +020022 buf->sample_size = sample_size;
Paul Cercueilf88f8852014-04-01 11:50:59 +020023 buf->length = buf->sample_size * samples_count;
Paul Cercueila689cd92014-03-20 16:37:25 +010024 buf->dev = dev;
Paul Cercueil645ab972014-03-24 14:36:12 +010025 buf->mask = calloc(dev->words, sizeof(*buf->mask));
Paul Cercueila689cd92014-03-20 16:37:25 +010026 if (!buf->mask)
27 goto err_free_buf;
Paul Cercueila689cd92014-03-20 16:37:25 +010028
Paul Cercueilf88f8852014-04-01 11:50:59 +020029 buf->buffer = malloc(buf->length);
Paul Cercueilde5a3472014-04-01 14:09:56 +020030 if (!buf->buffer)
31 goto err_free_mask;
Paul Cercueila689cd92014-03-20 16:37:25 +010032
Paul Cercueilde5a3472014-04-01 14:09:56 +020033 if (!iio_device_open(dev))
34 return buf;
35err_free_mask:
Paul Cercueila689cd92014-03-20 16:37:25 +010036 free(buf->mask);
37err_free_buf:
38 free(buf);
39 return NULL;
40}
41
42void iio_buffer_destroy(struct iio_buffer *buffer)
43{
Paul Cercueilde5a3472014-04-01 14:09:56 +020044 iio_device_close(buffer->dev);
Paul Cercueila689cd92014-03-20 16:37:25 +010045 free(buffer->buffer);
Paul Cercueila689cd92014-03-20 16:37:25 +010046 free(buffer->mask);
47 free(buffer);
48}
49
Paul Cercueilcbe78562014-04-01 14:42:20 +020050ssize_t iio_buffer_refill(struct iio_buffer *buffer)
Paul Cercueila689cd92014-03-20 16:37:25 +010051{
52 ssize_t read = iio_device_read_raw(buffer->dev,
53 buffer->buffer, buffer->length,
Paul Cercueil645ab972014-03-24 14:36:12 +010054 buffer->mask, buffer->dev->words);
Paul Cercueilcbe78562014-04-01 14:42:20 +020055 if (read >= 0)
56 buffer->data_length = read;
57 return read;
Paul Cercueila689cd92014-03-20 16:37:25 +010058}
59
60static ssize_t callback_wrapper(const struct iio_channel *chn,
61 void *buf, void *d)
62{
63 struct callback_wrapper_data *data = d;
64 if (chn->index >= 0 && TEST_BIT(data->mask, chn->index))
65 return data->callback(chn, buf,
66 chn->format.length / 8, data->data);
67 else
68 return 0;
69}
70
71ssize_t iio_buffer_foreach_sample(struct iio_buffer *buffer,
72 ssize_t (*callback)(const struct iio_channel *,
73 void *, size_t, void *), void *d)
74{
75 struct callback_wrapper_data data = {
76 .callback = callback,
77 .data = d,
Paul Cercueil645ab972014-03-24 14:36:12 +010078 .mask = buffer->dev->mask,
Paul Cercueila689cd92014-03-20 16:37:25 +010079 };
80
81 if (buffer->data_length < buffer->sample_size)
82 return 0;
83
84 return iio_device_process_samples(buffer->dev,
Paul Cercueil645ab972014-03-24 14:36:12 +010085 buffer->mask, buffer->dev->words, buffer->buffer,
Paul Cercueila689cd92014-03-20 16:37:25 +010086 buffer->data_length, callback_wrapper, &data);
87}
Paul Cercueil95347b92014-03-21 09:50:17 +010088
89void * iio_buffer_first(const struct iio_buffer *buffer,
90 const struct iio_channel *chn)
91{
92 size_t len;
93 unsigned int i;
94 void *ptr = buffer->buffer;
95
Paul Cercueil645ab972014-03-24 14:36:12 +010096 if (!iio_channel_is_enabled(chn))
Paul Cercueil95347b92014-03-21 09:50:17 +010097 return iio_buffer_end(buffer);
98
99 for (i = 0; i < buffer->dev->nb_channels; i++) {
100 struct iio_channel *cur = buffer->dev->channels[i];
101 len = cur->format.length / 8;
102
103 /* NOTE: dev->channels are ordered by index */
104 if (cur->index < 0 || cur->index == chn->index)
105 break;
106
107 if ((uintptr_t) ptr % len)
108 ptr += len - ((uintptr_t) ptr % len);
109 ptr += len;
110 }
111
112 len = chn->format.length / 8;
113 if ((uintptr_t) ptr % len)
114 ptr += len - ((uintptr_t) ptr % len);
115 return ptr;
116}
117
118ptrdiff_t iio_buffer_step(const struct iio_buffer *buffer,
119 const struct iio_channel *chn)
120{
Paul Cercueil645ab972014-03-24 14:36:12 +0100121 return (ptrdiff_t) iio_device_get_sample_size_mask(buffer->dev,
122 buffer->mask, buffer->dev->words);
Paul Cercueil95347b92014-03-21 09:50:17 +0100123}
124
125void * iio_buffer_end(const struct iio_buffer *buffer)
126{
127 return buffer->buffer + buffer->data_length;
128}