forked from graeme-hattan/rpi_AD7705_test_software
-
Notifications
You must be signed in to change notification settings - Fork 10
/
AD7705Comm.h
192 lines (163 loc) · 3.54 KB
/
AD7705Comm.h
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#ifndef __AD7705COMM_H
#define __AD7705COMM_H
/*
* AD7705 class to read data at a given sampling rate
*
* Copyright (c) 2007 MontaVista Software, Inc.
* Copyright (c) 2007 Anton Vorontsov <[email protected]>
* Copyright (c) 2013-2022 Bernd Porr <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
*/
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <thread>
#include <string>
#ifndef NDEBUG
#define DEBUG
#endif
/**
* Callback for new samples which needs to be implemented by the main program.
* The function hasSample needs to be overloaded in the main program.
**/
class AD7705callback {
public:
/**
* Called after a sample has arrived.
* \param sample Contains the ADC reading in Volt.
**/
virtual void hasSample(float sample) = 0;
};
/**
* Contains all settings for the data acquisition.
**/
struct AD7705settings {
/**
* The SPI device in /dev used.
**/
std::string spiDevice = "/dev/spidev0.0";
/**
* Sampling rates
**/
enum SamplingRates {
FS50HZ = 0,
FS60HZ = 1,
FS250HZ = 2,
FS500HZ = 3
};
/**
* Sampling rate requested
**/
SamplingRates samplingRate = FS50HZ;
/**
* Gains of the PGA
**/
enum PGAGains {
G1 = 0,
G2 = 1,
G4 = 2,
G8 = 3,
G16 = 4,
G32 = 5,
G64 = 6,
G128 = 7
};
/**
* Requested gain
**/
PGAGains pgaGain = G1;
/**
* Channel indices
**/
enum AIN {
AIN1 = 0,
AIN2 = 1
};
/**
* Requested input channel (0 or 1)
**/
AIN channel = AIN1;
/**
* Unipolar or bipolar mode
**/
enum Modes {
Bipolar = 0,
Unipolar = 1
};
/**
* Unipolar or biploar
**/
Modes mode = Unipolar;
};
/**
* This class reads data from the AD7705 in the background (separate
* thread) and calls a callback function whenever data is available.
**/
class AD7705Comm {
public:
/**
* Constructor. Opens the SPI device and waits for to start
* the acquisition.
* \param settings All AD7705 settings.
**/
AD7705Comm(AD7705settings settings);
/**
* Destructor which makes sure the data acquisition
* has stopped.
**/
~AD7705Comm();
/**
* Registers the callback which is called whenever there is a sample.
* \param cb Pointer to the callback interface.
**/
void registerCallback(AD7705callback* cb);
/**
* Unregisters the callback to the callback interface.
**/
void unRegisterCallback();
/**
* Starts the data acquisition
**/
void start();
/**
* Stops the data acquistion
**/
void stop();
private:
const uint8_t mode = SPI_CPHA | SPI_CPOL;
const int drdy_GPIO = 22;
const uint32_t speed = 500000;
const uint16_t delay = 0;
const uint8_t bpw = 8;
static constexpr float ADC_REF = 2.5;
int fd = 0;
std::thread daqThread;
int running = 0;
AD7705callback* ad7705callback = nullptr;
AD7705settings ad7705settings;
int spi_transfer(int fd, uint8_t* tx, uint8_t* rx, int n);
void writeReset(int fd);
void writeReg(int fd, uint8_t v);
uint8_t readReg(int fd);
int16_t readData(int fd);
void run();
inline float pgaGain() {
return (float)(1 << ad7705settings.pgaGain);
}
inline uint8_t commReg() {
return ((uint8_t)(ad7705settings.channel));
}
static int getSysfsIRQfd(int gpio);
static int fdPoll(int gpio_fd, int timeoutus);
static void gpio_unexport(int gpio);
};
#endif