forked from zzzbatmand/AD5593R_PI_cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AD5593R.h
228 lines (171 loc) · 8.14 KB
/
AD5593R.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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/*
This library is for the AD5593R by analog instruments please refer to the datasheet
https://www.analog.com/media/en/technical-documentation/data-sheets/AD5593R.pdf
The AD5593R is a powerful 12-bit configurable DAC/ADC/GPIO chip connected through an I2C bus.
The chip also has an additional addressing pin dubbed a0, which will change the device's effectively
I2C address, by connecting this pin and specifying its location in the class construction it is possible to
connect several AD5593Rs on the same I2C bus and independently control them.
To enable the ADC/DAC functionality of the chip a reference voltage MUST be set, as all set voltages
must fall into the range 0-Vref, or 0-2xVref if set_(ADC/DAC)_max_2x_Vref is called. If these functions
return negative values please read their description as the cause will be reported by its value.
GPIO capabilities have not yet been added.
Lukas Janavicius, 2019
For contact information, projects, or more about me, please visit my GitHub or website linked below.
Janavicius.org
https://github.com/LukasJanavicius
*/
//////Definitions and imports//////
#include <cstdint>
#include <string>
// To enable debugging please place the following before the library import,
// and be sure to use Serial.begin() in the setup.
// AD5593R_DEBUG
#pragma once
//comment this line to disable debugging
#define AD5593R_DEBUG
#ifdef AD5593R_DEBUG
#define AD5593R_PRINT(...) ad5593r_print(__VA_ARGS__)
#define AD5593R_PRINTLN(...) ad5593r_println(__VA_ARGS__)
#else
#define AD5593R_PRINT(...)
#define AD5593R_PRINTLN(...)
#endif
#ifndef AD5593R_h
#define AD5593R_h
#endif
#define AD5593R_BUS_BASE_ADDR 0x10
//////Classes//////
class AD5593R {
public:
// This configuration structure contains arrays of booleans,
// each array follows the form [channel0,...,channel7]
// where a 1 indicates the channel should be configured as the name implies
// for example an array ADCs[8] = {1,1,0,0,0,0,0,0} will configure channels 0 and 1 as ADCs.
// a declaration of this structure should be defined in your code, and passed into configure().
// You should not double assign pins, as only the first declaration will be assigned.
struct configuration {
bool ADCs[8]; //ADC pins
bool DACs[8]; //DAC pins
bool GPIs[8]; //input pins
bool GPOs[8]; //output pins
};
configuration config;
// This structure contains arrays of
struct Read_write_values {
float ADCs[8];
float DACs[8];
bool GPI_reads[8];
bool GPO_writes[8];
};
Read_write_values values;
// constructor for the class, a0 is the digital pin connected to the AD5593R
// if no pin is specified it is assumed only one AD5593R is connected
AD5593R(const char* i2c_device_filepath, uint8_t i2c_addr = AD5593R_BUS_BASE_ADDR, int a0 = -1);
bool init();
//AD5593R(int a0 = -1);
// enables the internal reference voltage of 2.5 V
void enable_internal_Vref();
// disables the internal reference voltage of 2.5 V
void disable_internal_Vref();
// sets the maximum ADC input to 2x Vref
void set_ADC_max_2x_Vref();
// sets the maximum ADC input to 1x Vref
void set_ADC_max_1x_Vref();
// sets the maximum DAC output to 2x Vref
void set_DAC_max_2x_Vref();
// sets the maximum DAC output to 2x Vref
void set_DAC_max_1x_Vref();
// If you use an external reference voltage you should call this function. Failure to set the reference voltage,
// or enable the internal reference will mean that any DAC/ADC function call will result in an error!
void set_Vref(float Vref);
//configures the selected channel as a DAC
void configure_DAC(uint8_t channel);
void configure_DACs(bool* channels);
// Sets the output voltage value of a given channel, returns 1 if the write is completed
// if the function returns -1 if the specified channel is not an DAC,
// if no reference voltage is specified a -2 will be returned,
// and if the voltage exceeds the maximum allowable voltage a -3 will be returned.
int write_DAC(uint8_t channel, float voltage);
void write_DACs(float* voltages);
//configures the selected channel as a ADC
void configure_ADC(uint8_t channel);
void configure_ADCs(bool* channels);
// Reads the voltage value of a given ADC channel, returns the Voltage if the write is completed
// if the function returns -1 if the specified channel is not an ADC,
// and if no reference voltage is specified a -2 will be returned.
float read_ADC(uint8_t channel);
float* read_ADCs();
void configure_GPI(uint8_t channel);
void configure_GPIs(bool* channels);
void configure_GPO(uint8_t channel);
void configure_GPOs(bool* channels);
bool* read_GPIs();
void write_GPOs(bool* pin_states);
int write_GPO(uint8_t, bool);
/*
// By passing in the configuration structure this function assigns the functionality
// to each pin, as described in the configuration. As stated above, you should not
// assign multiple functionalities to a single pin. In this event the function will return
// -1 and print an error if debug is enabled. A 1 will be returned if the configuration is successful
int configure_pins(*configuration config);
//call this function in
void update(DAC_Writes[8],ADC_Reads[8]);
// performs a software reset, generally a good idea to call in the setup
void reset();
// Reads the set value of a given DAC channel, -1 will be returned if
float read_DAC(int channel);
//This follows the same functionality as read_ADC(), but instead of reading from a single channel
//the configuration is passed in, so that all of the ADCs are read.
// In order to extract the values read you should pass in your Read_write_values struct.
float read_DACs(int channels[8], *Read_write_values output);
//power down a specific channel, if none is specified all channels are powered down.
void power_down(int channel = -1);
*/
private:
// Functions added for Raspberry port
uint8_t ad5593r_write(uint8_t addr, uint8_t msb, uint8_t lsb);
uint16_t ad5593r_read(uint8_t addr);
void ad5593r_print(std::string data);
void ad5593r_print(uint8_t data);
void ad5593r_print(int data);
void ad5593r_print(float data);
void ad5593r_println(std::string data);
// checks if the given channel is configured as an ADC
// returns 1 if the channel is configured, 0 if the channel is not
bool is_ADC(int channel);
// checks if the given channel is configured as a DAC
// returns 1 if the channel is configured, 0 if the channel is not
bool is_DAC(int channel);
// pointers for configuring the control registers, refer to the data sheet for functionality
// These structures are adapted from
// https://github.com/MikroElektronika/HEXIWEAR/blob/master/SW/Click%20Examples%20mikroC/examples/ADAC/library/__ADAC_Driver.h
unsigned int _num_of_channels = 8;
int _a0;
//general purpose control register data Bytes
uint8_t _GPRC_msbs;
uint8_t _GPRC_lsbs;
//GPO states
uint8_t _GPO_states;
// power control register data bytes;
uint8_t _PCR_msbs;
uint8_t _PCR_lsbs;
uint8_t _DAC_config;
uint8_t _ADC_config;
uint8_t _GPI_config;
uint8_t _GPO_config;
//default address of the AD5593R, multiple devices are handled by setting the desired device's a0 to LOW
//by default the a0 pin will be pulled high, effectively changing its address. For more information on the addressing please
//refer to the data sheet in the introduction
//uint8_t _i2c_address = 0x10;
//Value of the reference voltage, if none is specified then all ADC/DAC functions will throw errors
float _Vref = -1;
//flag for 2xVref mode
bool _ADC_2x_mode = 0;
//flag for 2xVref mode
bool _DAC_2x_mode = 0;
float _ADC_max = -1;
float _DAC_max = -1;
uint8_t i2c_bus_addr;
int i2c_file;
std::string i2c_filepath;
};