-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAdc.cpp
110 lines (101 loc) · 3.11 KB
/
Adc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
* Adc.cc
*
* Created on: Mar 5, 2015
* Author: mlaakso
*/
#include <cerrno>
#include <cstring>
#include <string>
#include <stdexcept>
#include "Adc.h"
namespace PowerMonitor
{
GalileoGen2Adc::GalileoGen2Adc(unsigned int nChannels, unsigned int freq) :
_nChannels(nChannels)
{
int ret;
_iioctx = iio_create_local_context();
if (_iioctx == nullptr)
{
throw std::runtime_error("Could not create iio context.");
}
_adc = iio_context_find_device(_iioctx, "adc1x8s102");
if (_adc == nullptr)
{
iio_context_destroy(_iioctx);
throw std::runtime_error("Could not find iio device.");
}
_trigger = iio_context_find_device(_iioctx, "hrtimer_trig0");
if (_trigger == nullptr)
{
iio_context_destroy(_iioctx);
throw std::runtime_error("Could not find iio trigger device.");
}
ret = iio_device_attr_write_longlong(_trigger, "frequency", freq);
if (ret < 0)
{
iio_context_destroy(_iioctx);
throw std::runtime_error("Could not set sampling frequency: " + std::string(strerror(ret)));
}
// Associate trigger with ADC.
ret = iio_device_set_trigger(_adc, _trigger);
if (ret < 0)
{
iio_context_destroy(_iioctx);
throw std::runtime_error("Could not associate trigger: " + std::string(strerror(ret)));
}
// Enable ADC channels.
unsigned int n = iio_device_get_channels_count(_adc);
for (unsigned int i = 0; i < n; ++i)
{
if (i < nChannels)
iio_channel_enable(iio_device_get_channel(_adc, i));
else
iio_channel_disable(iio_device_get_channel(_adc, i));
}
// Create a buffer holding 1 second worth of values.
_adcbuf = iio_device_create_buffer(_adc, freq, false);
if (_adcbuf == nullptr)
{
iio_context_destroy(_iioctx);
throw std::runtime_error("Could not create iio buffer: " + std::string(strerror(errno)));
}
}
GalileoGen2Adc::~GalileoGen2Adc()
{
iio_buffer_destroy(_adcbuf);
iio_context_destroy(_iioctx);
}
void GalileoGen2Adc::refill()
{
ssize_t bytes = iio_buffer_refill(_adcbuf);
if (bytes < 0)
{
throw std::runtime_error("Could not read iio buffer: " + std::string(strerror(bytes)));
}
}
GalileoGen2Adc::const_iterator GalileoGen2Adc::cbegin(unsigned int channel) const
{
struct iio_channel* chn = iio_device_get_channel(_adc, channel);
if (chn == nullptr)
{
throw std::runtime_error("Invalid channel index.");
}
char* ptr = (char*) iio_buffer_first(_adcbuf, chn);
return const_iterator(ptr, iio_buffer_step(_adcbuf), chn);
}
GalileoGen2Adc::const_iterator GalileoGen2Adc::cend(unsigned int channel) const
{
struct iio_channel* chn = iio_device_get_channel(_adc, channel);
if (chn == nullptr)
{
throw std::runtime_error("Invalid channel index.");
}
char* start = (char*) iio_buffer_start(_adcbuf);
char* ptr = (char*) iio_buffer_first(_adcbuf, chn);
char* end = (char*) iio_buffer_end(_adcbuf);
ptrdiff_t distance = end - start;
return const_iterator(ptr + distance, iio_buffer_step(_adcbuf), chn);
}
}