Don't sync the ADC on creation.
[ruwai.git] / software / arduino / libraries / rw_adc / rw_adc.cpp
blob585ca3e922d8a27a09be48579a202648aad34ef6
1 // -*- coding: utf-8 -*-
2 // LICENSE
3 //
4 // This file is part of ruwai.
5 //
6 // If you use ruwai in any program or publication, please inform and
7 // acknowledge its author Stefan Mertl (stefan@mertl-research.at).
8 //
9 // pSysmon is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 3 of the License, or
12 // (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <rw_adc.h>
24 #include <ruwai.h>
25 #include <SPI.h>
26 #include <Wire.h>
28 extern volatile bool samples_ready;
30 RwAdc::RwAdc(uint8_t port_expander_address, uint8_t pga1_address, uint8_t pga2_address, uint8_t pga3_address, uint8_t pga4_address):pga1(pga1_address), pga2(pga2_address), pga3(pga3_address), pga4(pga4_address)
32 pwdn_port_expander = port_expander_address;
35 void
36 RwAdc::begin(adc_mode_t adc_mode, adc_output_format_t adc_output_format)
38 // Initialize the Arduino pins.
39 //pinMode(ADC_DRDY, INPUT);
40 pinMode(ADC_SYNC, OUTPUT);
41 pinMode(ADC_MODE0, OUTPUT);
42 pinMode(ADC_MODE1, OUTPUT);
43 pinMode(ADC_FORMAT0, OUTPUT);
44 pinMode(ADC_CLKDIV, OUTPUT);
46 // Initialize the SPI interface.
47 SPI.setDataMode(SPI_MODE1);
48 SPI.setBitOrder(MSBFIRST);
49 // TODO: Check which clock divider fits for which sampling rate.
50 SPI.setClockDivider(SPI_CLOCK_DIV4);
51 SPI.begin();
52 delay(200);
54 // Initialize the channels.
55 channel1_enable = 1;
56 channel2_enable = 1;
57 channel3_enable = 1;
58 channel4_enable = 1;
60 set_mode(adc_mode);
61 set_output_format(adc_output_format);
63 digitalWrite(ADC_SYNC, LOW);
66 void
67 RwAdc::request_data(void)
69 uint32_t tmp;
70 static uint32_t counter = 65536;
72 switch (output_format)
74 case ADC_FORMAT_SPI_TDM_DYNAMIC:
76 if (channel1_enable)
78 // Request data of channel 1.
79 samples[0] = SPI.transfer(0);
80 samples[0] = (samples[0] << 8) + SPI.transfer(0);
81 samples[0] = (samples[0] << 8) + SPI.transfer(0);
83 else
85 samples[0] = 0;
88 if (channel2_enable)
90 // Request data of channel 2.
91 samples[1] = SPI.transfer(0);
92 samples[1] = (samples[1] << 8) + SPI.transfer(0);
93 samples[1] = (samples[1] << 8) + SPI.transfer(0);
95 else
97 samples[1] = 0;
100 if (channel3_enable)
102 // Request data of channel 3.
103 samples[2] = SPI.transfer(0);
104 samples[2] = (samples[2] << 8) + SPI.transfer(0);
105 samples[2] = (samples[2] << 8) + SPI.transfer(0);
107 else
109 samples[2] = 0;
112 if (channel4_enable)
114 // Request data of channel 4.
115 samples[3] = SPI.transfer(0);
116 samples[3] = (samples[3] << 8) + SPI.transfer(0);
117 samples[3] = (samples[3] << 8) + SPI.transfer(0);
119 else
121 samples[3] = 0;
123 samples_ready = true;
125 break;
126 case ADC_FORMAT_SPI_TDM_FIXED:
127 // Request data of channel 1.
128 tmp = SPI.transfer(0);
129 tmp = (tmp << 8) + SPI.transfer(0);
130 tmp = (tmp << 8) + SPI.transfer(0);
131 samples[0] = convert_24bit_to_int(tmp);
133 // Request data of channel 2.
134 tmp = SPI.transfer(0);
135 tmp = (tmp << 8) + SPI.transfer(0);
136 tmp = (tmp << 8) + SPI.transfer(0);
137 samples[1] = convert_24bit_to_int(tmp);
139 // Request data of channel 3.
140 tmp = SPI.transfer(0);
141 tmp = (tmp << 8) + SPI.transfer(0);
142 tmp = (tmp << 8) + SPI.transfer(0);
143 samples[2] = convert_24bit_to_int(tmp);
145 // Request data of channel 4.
146 tmp = SPI.transfer(0);
147 tmp = (tmp << 8) + SPI.transfer(0);
148 tmp = (tmp << 8) + SPI.transfer(0);
149 //tmp = (uint32_t) counter;
150 samples[3] = convert_24bit_to_int(tmp);
151 counter += 10;
153 if (counter == 8388606)
155 counter = 65536;
159 digitalWrite(49, HIGH);
160 samples_ready = true;
161 break;
167 void
168 RwAdc::enable_channel(uint8_t channel_number)
170 uint8_t pwdn = 0;
171 if(channel_number == 1)
173 channel1_enable = 1;
175 else if(channel_number == 2)
177 channel2_enable = 1;
179 else if(channel_number == 3)
181 channel3_enable = 1;
183 else if(channel_number == 4)
185 channel4_enable = 1;
187 pwdn = ((channel1_enable << PCF_PORT_PWDN1) | (channel2_enable << PCF_PORT_PWDN2) | (channel3_enable << PCF_PORT_PWDN3) | (channel4_enable << PCF_PORT_PWDN4));
188 Wire.beginTransmission(pwdn_port_expander);
189 Wire.write(pwdn);
190 Wire.endTransmission(pwdn_port_expander);
194 void
195 RwAdc::disable_channel(uint8_t channel_number)
197 uint8_t pwdn = 0;
198 if(channel_number == 1)
200 channel1_enable = 0;
202 else if(channel_number == 2)
204 channel2_enable = 0;
206 else if(channel_number == 3)
208 channel3_enable = 0;
210 else if(channel_number == 4)
212 channel4_enable = 0;
214 pwdn = ((channel1_enable << PCF_PORT_PWDN1) | (channel2_enable << PCF_PORT_PWDN2) | (channel3_enable << PCF_PORT_PWDN3) | (channel4_enable << PCF_PORT_PWDN4));
215 Wire.beginTransmission(pwdn_port_expander);
216 Wire.write(pwdn);
217 Wire.endTransmission(pwdn_port_expander);
221 void
222 RwAdc::set_gain(uint8_t channel_number, pga_gain_t gain)
224 switch (channel_number)
226 case 1:
227 pga1.set_gain(gain);
228 break;
229 case 2:
230 pga2.set_gain(gain);
231 break;
232 case 3:
233 pga3.set_gain(gain);
234 break;
235 case 4:
236 pga4.set_gain(gain);
237 break;
241 void
242 RwAdc::set_mode(adc_mode_t adc_mode)
244 uint8_t clkdiv_pin_val;
245 uint8_t mode0_pin_val;
246 uint8_t mode1_pin_val;
247 mode = adc_mode;
248 switch (adc_mode)
250 case ADC_MODE_HIGHSPEED:
251 clkdiv_pin_val = 1;
252 mode0_pin_val = 0;
253 mode1_pin_val = 0;
254 clkdiv = ADC_CLKDIV_HIGHSPEED_1;
255 oversampling = ADC_OVERSAMPLING;
256 break;
257 case ADC_MODE_HIGHRES:
258 clkdiv_pin_val = 1;
259 mode0_pin_val = 1;
260 mode1_pin_val = 0;
261 clkdiv = ADC_CLKDIV_HIGHRES_1;
262 oversampling = ADC_OVERSAMPLING_HIGH_RES;
263 break;
264 case ADC_MODE_LOWPOW_CLKDIV_0:
265 clkdiv_pin_val = 0;
266 mode0_pin_val = 0;
267 mode1_pin_val = 1;
268 clkdiv = ADC_CLKDIV_LOWPOW_0;
269 oversampling = ADC_OVERSAMPLING;
270 break;
271 case ADC_MODE_LOWPOW_CLKDIV_1:
272 clkdiv_pin_val = 1;
273 mode0_pin_val = 0;
274 mode1_pin_val = 1;
275 clkdiv = ADC_CLKDIV_LOWPOW_1;
276 oversampling = ADC_OVERSAMPLING;
277 break;
278 case ADC_MODE_LOWSPEED_CLKDIV_0:
279 clkdiv_pin_val = 0;
280 mode0_pin_val = 1;
281 mode1_pin_val = 1;
282 clkdiv = ADC_CLKDIV_LOWSPEED_0;
283 oversampling = ADC_OVERSAMPLING;
284 break;
285 case ADC_MODE_LOWSPEED_CLKDIV_1:
286 clkdiv_pin_val = 1;
287 mode0_pin_val = 1;
288 mode1_pin_val = 1;
289 clkdiv = ADC_CLKDIV_LOWSPEED_1;
290 oversampling = ADC_OVERSAMPLING;
291 break;
294 digitalWrite(ADC_CLKDIV, clkdiv_pin_val);
295 digitalWrite(ADC_MODE0, mode0_pin_val);
296 digitalWrite(ADC_MODE1, mode1_pin_val);
301 void
302 RwAdc::set_output_format(adc_output_format_t adc_output_format)
304 uint8_t format_pin_val;
305 output_format = adc_output_format;
307 switch (output_format)
309 case ADC_FORMAT_SPI_TDM_DYNAMIC:
310 format_pin_val = 0;
311 break;
312 case ADC_FORMAT_SPI_TDM_FIXED:
313 format_pin_val = 1;
314 break;
317 digitalWrite(ADC_FORMAT0, format_pin_val);
321 uint32_t
322 RwAdc::get_clk_freq(uint16_t adc_sampling_rate)
324 uint32_t clk;
325 sampling_rate = adc_sampling_rate;
326 clk = (uint32_t)sampling_rate * (uint32_t)clkdiv * (uint32_t)oversampling;
327 return clk;
331 int32_t
332 RwAdc::convert_24bit_to_int(uint32_t value)
334 uint8_t sign_bit;
336 sign_bit = (value >> 23) & 1;
338 if (sign_bit == 1)
340 // Handle negative values.
341 //value = value - 1;
342 //value = (~value) & (uint32_t) 0xFFFFFF;
343 //return (int32_t) value * (int32_t) -1;
344 return (int32_t) (value | (uint32_t) 0xFF000000);
346 else
348 // Handle positive values.
349 return (int32_t) value;