1 // -*- coding: utf-8 -*-
4 // This file is part of ruwai.
6 // If you use ruwai in any program or publication, please inform and
7 // acknowledge its author Stefan Mertl (stefan@mertl-research.at).
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/>.
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
;
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
);
54 // Initialize the channels.
61 set_output_format(adc_output_format
);
63 digitalWrite(ADC_SYNC
, LOW
);
67 RwAdc::request_data(void)
70 static uint32_t counter
= 65536;
72 switch (output_format
)
74 case ADC_FORMAT_SPI_TDM_DYNAMIC
:
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);
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);
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);
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);
123 samples_ready = true;
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
);
153 if (counter
== 8388606)
159 digitalWrite(49, HIGH
);
160 samples_ready
= true;
168 RwAdc::enable_channel(uint8_t channel_number
)
171 if(channel_number
== 1)
175 else if(channel_number
== 2)
179 else if(channel_number
== 3)
183 else if(channel_number
== 4)
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
);
190 Wire
.endTransmission(pwdn_port_expander
);
195 RwAdc::disable_channel(uint8_t channel_number
)
198 if(channel_number
== 1)
202 else if(channel_number
== 2)
206 else if(channel_number
== 3)
210 else if(channel_number
== 4)
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
);
217 Wire
.endTransmission(pwdn_port_expander
);
222 RwAdc::set_gain(uint8_t channel_number
, pga_gain_t gain
)
224 switch (channel_number
)
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
;
250 case ADC_MODE_HIGHSPEED
:
254 clkdiv
= ADC_CLKDIV_HIGHSPEED_1
;
255 oversampling
= ADC_OVERSAMPLING
;
257 case ADC_MODE_HIGHRES
:
261 clkdiv
= ADC_CLKDIV_HIGHRES_1
;
262 oversampling
= ADC_OVERSAMPLING_HIGH_RES
;
264 case ADC_MODE_LOWPOW_CLKDIV_0
:
268 clkdiv
= ADC_CLKDIV_LOWPOW_0
;
269 oversampling
= ADC_OVERSAMPLING
;
271 case ADC_MODE_LOWPOW_CLKDIV_1
:
275 clkdiv
= ADC_CLKDIV_LOWPOW_1
;
276 oversampling
= ADC_OVERSAMPLING
;
278 case ADC_MODE_LOWSPEED_CLKDIV_0
:
282 clkdiv
= ADC_CLKDIV_LOWSPEED_0
;
283 oversampling
= ADC_OVERSAMPLING
;
285 case ADC_MODE_LOWSPEED_CLKDIV_1
:
289 clkdiv
= ADC_CLKDIV_LOWSPEED_1
;
290 oversampling
= ADC_OVERSAMPLING
;
294 digitalWrite(ADC_CLKDIV
, clkdiv_pin_val
);
295 digitalWrite(ADC_MODE0
, mode0_pin_val
);
296 digitalWrite(ADC_MODE1
, mode1_pin_val
);
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
:
312 case ADC_FORMAT_SPI_TDM_FIXED
:
317 digitalWrite(ADC_FORMAT0
, format_pin_val
);
322 RwAdc::get_clk_freq(uint16_t adc_sampling_rate
)
325 sampling_rate
= adc_sampling_rate
;
326 clk
= (uint32_t)sampling_rate
* (uint32_t)clkdiv
* (uint32_t)oversampling
;
332 RwAdc::convert_24bit_to_int(uint32_t value
)
336 sign_bit
= (value
>> 23) & 1;
340 // Handle negative values.
342 //value = (~value) & (uint32_t) 0xFFFFFF;
343 //return (int32_t) value * (int32_t) -1;
344 return (int32_t) (value
| (uint32_t) 0xFF000000);
348 // Handle positive values.
349 return (int32_t) value
;