blob: f41bc80488cba886e458e7f1f8d4b3a5b670bdf2 [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,
10 size_t length)
11{
Paul Cercueila689cd92014-03-20 16:37:25 +010012 struct iio_buffer *buf = malloc(sizeof(*buf));
13 if (!buf)
14 return NULL;
15
16 buf->data_length = 0;
17 buf->length = length;
18 buf->dev = dev;
Paul Cercueil645ab972014-03-24 14:36:12 +010019 buf->mask = calloc(dev->words, sizeof(*buf->mask));
Paul Cercueila689cd92014-03-20 16:37:25 +010020 if (!buf->mask)
21 goto err_free_buf;
Paul Cercueila689cd92014-03-20 16:37:25 +010022
Paul Cercueil645ab972014-03-24 14:36:12 +010023 buf->sample_size = iio_device_get_sample_size(dev);
Paul Cercueila689cd92014-03-20 16:37:25 +010024
25 buf->buffer = malloc(length);
26 if (buf->buffer)
27 return buf;
28
Paul Cercueila689cd92014-03-20 16:37:25 +010029 free(buf->mask);
30err_free_buf:
31 free(buf);
32 return NULL;
33}
34
35void iio_buffer_destroy(struct iio_buffer *buffer)
36{
37 free(buffer->buffer);
Paul Cercueila689cd92014-03-20 16:37:25 +010038 free(buffer->mask);
39 free(buffer);
40}
41
42int iio_buffer_refill(struct iio_buffer *buffer)
43{
44 ssize_t read = iio_device_read_raw(buffer->dev,
45 buffer->buffer, buffer->length,
Paul Cercueil645ab972014-03-24 14:36:12 +010046 buffer->mask, buffer->dev->words);
Paul Cercueila689cd92014-03-20 16:37:25 +010047 if (read < 0)
48 return (int) read;
49
50 buffer->data_length = read;
51 return 0;
52}
53
54static ssize_t callback_wrapper(const struct iio_channel *chn,
55 void *buf, void *d)
56{
57 struct callback_wrapper_data *data = d;
58 if (chn->index >= 0 && TEST_BIT(data->mask, chn->index))
59 return data->callback(chn, buf,
60 chn->format.length / 8, data->data);
61 else
62 return 0;
63}
64
65ssize_t iio_buffer_foreach_sample(struct iio_buffer *buffer,
66 ssize_t (*callback)(const struct iio_channel *,
67 void *, size_t, void *), void *d)
68{
69 struct callback_wrapper_data data = {
70 .callback = callback,
71 .data = d,
Paul Cercueil645ab972014-03-24 14:36:12 +010072 .mask = buffer->dev->mask,
Paul Cercueila689cd92014-03-20 16:37:25 +010073 };
74
75 if (buffer->data_length < buffer->sample_size)
76 return 0;
77
78 return iio_device_process_samples(buffer->dev,
Paul Cercueil645ab972014-03-24 14:36:12 +010079 buffer->mask, buffer->dev->words, buffer->buffer,
Paul Cercueila689cd92014-03-20 16:37:25 +010080 buffer->data_length, callback_wrapper, &data);
81}
Paul Cercueil95347b92014-03-21 09:50:17 +010082
83void * iio_buffer_first(const struct iio_buffer *buffer,
84 const struct iio_channel *chn)
85{
86 size_t len;
87 unsigned int i;
88 void *ptr = buffer->buffer;
89
Paul Cercueil645ab972014-03-24 14:36:12 +010090 if (!iio_channel_is_enabled(chn))
Paul Cercueil95347b92014-03-21 09:50:17 +010091 return iio_buffer_end(buffer);
92
93 for (i = 0; i < buffer->dev->nb_channels; i++) {
94 struct iio_channel *cur = buffer->dev->channels[i];
95 len = cur->format.length / 8;
96
97 /* NOTE: dev->channels are ordered by index */
98 if (cur->index < 0 || cur->index == chn->index)
99 break;
100
101 if ((uintptr_t) ptr % len)
102 ptr += len - ((uintptr_t) ptr % len);
103 ptr += len;
104 }
105
106 len = chn->format.length / 8;
107 if ((uintptr_t) ptr % len)
108 ptr += len - ((uintptr_t) ptr % len);
109 return ptr;
110}
111
112ptrdiff_t iio_buffer_step(const struct iio_buffer *buffer,
113 const struct iio_channel *chn)
114{
Paul Cercueil645ab972014-03-24 14:36:12 +0100115 return (ptrdiff_t) iio_device_get_sample_size_mask(buffer->dev,
116 buffer->mask, buffer->dev->words);
Paul Cercueil95347b92014-03-21 09:50:17 +0100117}
118
119void * iio_buffer_end(const struct iio_buffer *buffer)
120{
121 return buffer->buffer + buffer->data_length;
122}