Added comparator
[hackover2013-badge-firmware.git] / drivers / adc / ads1015 / ads1015.c
1 /**************************************************************************/
2 /*!
3 @file ads1015.c
4 @author K. Townsend (microBuilder.eu)
5
6 @brief Drivers for the TI ADS1015 12-Bit I2C ADC
7
8 @section DESCRIPTION
9
10 The ADS1015 is a 4-channel, 12-bit I2C ADC with a programmable
11 comparator and an internal PGA (from 2/3 to 16x gain). It can be
12 configured for four single-ended channels or two differential inputs.
13 The comparator can be used in both traditional and windowed mode.
14
15 @section LICENSE
16
17 Software License Agreement (BSD License)
18
19 Copyright (c) 2012, K. Townsend
20 All rights reserved.
21
22 Redistribution and use in source and binary forms, with or without
23 modification, are permitted provided that the following conditions are met:
24 1. Redistributions of source code must retain the above copyright
25 notice, this list of conditions and the following disclaimer.
26 2. Redistributions in binary form must reproduce the above copyright
27 notice, this list of conditions and the following disclaimer in the
28 documentation and/or other materials provided with the distribution.
29 3. Neither the name of the copyright holders nor the
30 names of its contributors may be used to endorse or promote products
31 derived from this software without specific prior written permission.
32
33 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
34 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
37 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
40 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 */
44 /**************************************************************************/
45 #include "ads1015.h"
46 #include "core/systick/systick.h"
47
48 extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];
49 extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];
50 extern volatile uint32_t I2CReadLength, I2CWriteLength;
51
52 static bool _ads1015Initialised = false;
53
54 /**************************************************************************/
55 /*!
56 @brief Sends a single command byte over I2C
57 */
58 /**************************************************************************/
59 static ads1015Error_t ads1015WriteRegister (uint8_t reg, uint16_t value)
60 {
61 ads1015Error_t error = ADS1015_ERROR_OK;
62
63 // Clear write buffers
64 uint32_t i;
65 for ( i = 0; i < I2C_BUFSIZE; i++ )
66 {
67 I2CMasterBuffer[i] = 0x00;
68 }
69
70 I2CWriteLength = 4;
71 I2CReadLength = 0;
72 I2CMasterBuffer[0] = ADS1015_ADDRESS; // I2C device address
73 I2CMasterBuffer[1] = reg; // Register
74 I2CMasterBuffer[2] = value >> 8; // Upper 8-bits
75 I2CMasterBuffer[3] = value & 0xFF; // Lower 8-bits
76 i2cEngine();
77
78 // ToDo: Add in proper I2C error-checking
79 return error;
80 }
81
82 /**************************************************************************/
83 /*!
84 @brief Reads a 16 bit values over I2C
85 */
86 /**************************************************************************/
87 static ads1015Error_t ina219Read16(uint8_t reg, uint16_t *value)
88 {
89 ads1015Error_t error = ADS1015_ERROR_OK;
90
91 // Clear write buffers
92 uint32_t i;
93 for ( i = 0; i < I2C_BUFSIZE; i++ )
94 {
95 I2CMasterBuffer[i] = 0x00;
96 }
97
98 I2CWriteLength = 2;
99 I2CReadLength = 2;
100 I2CMasterBuffer[0] = ADS1015_ADDRESS; // I2C device address
101 I2CMasterBuffer[1] = reg; // Command register
102 // Append address w/read bit
103 I2CMasterBuffer[2] = ADS1015_ADDRESS | ADS1015_READBIT;
104 i2cEngine();
105
106 // Shift values to create properly formed integer
107 *value = ((I2CSlaveBuffer[0] << 8) | I2CSlaveBuffer[1]);
108
109 // ToDo: Add in proper I2C error-checking
110 return error;
111 }
112
113 /**************************************************************************/
114 /*!
115 @brief Initialises the I2C block
116 */
117 /**************************************************************************/
118 ads1015Error_t ads1015Init(void)
119 {
120 ads1015Error_t error = ADS1015_ERROR_OK;
121
122 // Initialise I2C
123 if (i2cInit(I2CMASTER) == false)
124 {
125 return ADS1015_ERROR_I2CINIT; /* Fatal error */
126 }
127
128 _ads1015Initialised = true;
129 return error;
130 }
131
132 /**************************************************************************/
133 /*!
134 @brief Reads the 12-bit conversion results from the specified channel
135 */
136 /**************************************************************************/
137 ads1015Error_t ads1015ReadADC_SingleEnded(uint8_t channel, uint16_t *value)
138 {
139 ads1015Error_t error = ADS1015_ERROR_OK;
140
141 if (!(_ads1015Initialised))
142 {
143 ads1015Init();
144 }
145
146 if (channel > 3)
147 {
148 *value = 0;
149 return ADS1015_ERROR_INVALIDCHANNEL;
150 }
151
152 // Start with default values
153 uint16_t config = ADS1015_REG_CONFIG_CQUE_NONE | // Disable the comparator (default val)
154 ADS1015_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val)
155 ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
156 ADS1015_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val)
157 ADS1015_REG_CONFIG_DR_1600SPS | // 1600 samples per second (default)
158 ADS1015_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default)
159
160 // Set PGA/voltage range
161 config |= ADS1015_REG_CONFIG_PGA_6_144V; // +/- 6.144V range (limited to VDD +0.3V max!)
162
163 // Set single-ended input channel
164 switch (channel)
165 {
166 case (0):
167 config |= ADS1015_REG_CONFIG_MUX_SINGLE_0;
168 break;
169 case (1):
170 config |= ADS1015_REG_CONFIG_MUX_SINGLE_1;
171 break;
172 case (2):
173 config |= ADS1015_REG_CONFIG_MUX_SINGLE_2;
174 break;
175 case (3):
176 config |= ADS1015_REG_CONFIG_MUX_SINGLE_3;
177 break;
178 }
179
180 // Set 'start single-conversion' bit
181 config |= ADS1015_REG_CONFIG_OS_SINGLE;
182
183 // Write config register to the ADC
184 error = ads1015WriteRegister(ADS1015_REG_POINTER_CONFIG, config);
185 if (error) return error;
186
187 // Wait for the conversion to complete
188 systickDelay(1);
189
190 // Read the conversion results
191 error = ina219Read16(ADS1015_REG_POINTER_CONVERT, value);
192 if (error) return error;
193
194 // Shift results 4-bits to the right
195 *value = *value >> 4;
196
197 return error;
198 }
199
200 /**************************************************************************/
201 /*!
202 @brief Reads the 12-bit conversion results, measuring the voltage
203 difference between the P (AIN0) and N (AIN1) input. Generates
204 a signed 12-bit value since the difference can be either
205 positive or negative.
206 */
207 /**************************************************************************/
208 ads1015Error_t ads1015ReadADC_Differential_0_1(int16_t *value)
209 {
210 ads1015Error_t error = ADS1015_ERROR_OK;
211
212 if (!(_ads1015Initialised))
213 {
214 ads1015Init();
215 }
216
217 // Start with default values
218 uint16_t config = ADS1015_REG_CONFIG_CQUE_NONE | // Disable the comparator (default val)
219 ADS1015_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val)
220 ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
221 ADS1015_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val)
222 ADS1015_REG_CONFIG_DR_1600SPS | // 1600 samples per second (default)
223 ADS1015_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default)
224
225 // Set PGA/voltage range
226 config |= ADS1015_REG_CONFIG_PGA_6_144V; // +/- 6.144V range (limited to VDD +0.3V max!)
227
228 // Set channels
229 config |= ADS1015_REG_CONFIG_MUX_DIFF_0_1; // AIN0 = P, AIN1 = N
230
231 // Set 'start single-conversion' bit
232 config |= ADS1015_REG_CONFIG_OS_SINGLE;
233
234 // Write config register to the ADC
235 error = ads1015WriteRegister(ADS1015_REG_POINTER_CONFIG, config);
236 if (error) return error;
237
238 // Wait for the conversion to complete
239 systickDelay(1);
240
241 // Read the conversion results
242 error = ina219Read16(ADS1015_REG_POINTER_CONVERT, value);
243 if (error) return error;
244
245 // Shift results 4-bits to the right
246 *value = *value >> 4;
247
248 return error;
249 }
250
251 /**************************************************************************/
252 /*!
253 @brief Reads the 12-bit conversion results, measuring the voltage
254 difference between the P (AIN2) and N (AIN3) input. Generates
255 a signed 12-bit value since the difference can be either
256 positive or negative.
257 */
258 /**************************************************************************/
259 ads1015Error_t ads1015ReadADC_Differential_2_3(int16_t *value)
260 {
261 ads1015Error_t error = ADS1015_ERROR_OK;
262
263 if (!(_ads1015Initialised))
264 {
265 ads1015Init();
266 }
267
268 // Start with default values
269 uint16_t config = ADS1015_REG_CONFIG_CQUE_NONE | // Disable the comparator (default val)
270 ADS1015_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val)
271 ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
272 ADS1015_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val)
273 ADS1015_REG_CONFIG_DR_1600SPS | // 1600 samples per second (default)
274 ADS1015_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default)
275
276 // Set PGA/voltage range
277 config |= ADS1015_REG_CONFIG_PGA_6_144V; // +/- 6.144V range (limited to VDD +0.3V max!)
278
279 // Set channels
280 config |= ADS1015_REG_CONFIG_MUX_DIFF_2_3; // AIN2 = P, AIN3 = N
281
282 // Set 'start single-conversion' bit
283 config |= ADS1015_REG_CONFIG_OS_SINGLE;
284
285 // Write config register to the ADC
286 error = ads1015WriteRegister(ADS1015_REG_POINTER_CONFIG, config);
287 if (error) return error;
288
289 // Wait for the conversion to complete
290 systickDelay(1);
291
292 // Read the conversion results
293 error = ina219Read16(ADS1015_REG_POINTER_CONVERT, value);
294 if (error) return error;
295
296 // Shift results 4-bits to the right
297 *value = *value >> 4;
298
299 return error;
300 }
301
302 /**************************************************************************/
303 /*!
304 @brief Sets up the comparator to operate in basic mode, causing the
305 ALERT/RDY pin to assert (go from high to low) when the ADC
306 value exceeds the specified threshold.
307
308 This will also set the ADC in continuous conversion mode.
309
310 @section EXAMPLE
311
312 @code
313 ads1015Init();
314
315 // Setup 3V comparator on channel 0
316 ads1015StartComparator_SingleEnded(0, 1000);
317
318 int16_t results;
319 while(1)
320 {
321 // Need to read to clear com bit once it's set
322 ads1015GetLastConversionResults(&results);
323 printf("%d\r\n", results);
324 }
325 @endcode
326 */
327 /**************************************************************************/
328 ads1015Error_t ads1015StartComparator_SingleEnded(uint8_t channel, int16_t threshold)
329 {
330 uint16_t value;
331
332 ads1015Error_t error = ADS1015_ERROR_OK;
333
334 if (!(_ads1015Initialised))
335 {
336 ads1015Init();
337 }
338
339 // Start with default values
340 uint16_t config = ADS1015_REG_CONFIG_CQUE_1CONV | // Comparator enabled and asserts on 1 match
341 ADS1015_REG_CONFIG_CLAT_LATCH | // Latching mode
342 ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
343 ADS1015_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val)
344 ADS1015_REG_CONFIG_DR_1600SPS | // 1600 samples per second (default)
345 ADS1015_REG_CONFIG_MODE_CONTIN | // Continuous conversion mode
346 ADS1015_REG_CONFIG_PGA_6_144V | // +/- 6.144V range (limited to VDD +0.3V max!)
347 ADS1015_REG_CONFIG_MODE_CONTIN; // Continuous conversion mode
348
349 // Set single-ended input channel
350 switch (channel)
351 {
352 case (0):
353 config |= ADS1015_REG_CONFIG_MUX_SINGLE_0;
354 break;
355 case (1):
356 config |= ADS1015_REG_CONFIG_MUX_SINGLE_1;
357 break;
358 case (2):
359 config |= ADS1015_REG_CONFIG_MUX_SINGLE_2;
360 break;
361 case (3):
362 config |= ADS1015_REG_CONFIG_MUX_SINGLE_3;
363 break;
364 }
365
366 // Set the high threshold register
367 error = ads1015WriteRegister(ADS1015_REG_POINTER_HITHRESH, threshold << 4);
368 if (error) return error;
369
370 // Write config register to the ADC
371 error = ads1015WriteRegister(ADS1015_REG_POINTER_CONFIG, config);
372 if (error) return error;
373 }
374
375 /**************************************************************************/
376 /*!
377 @brief In order to clear the comparator, we need to read the
378 conversion results. This function reads the last conversion
379 results without changing the config value.
380 */
381 /**************************************************************************/
382 ads1015Error_t ads1015GetLastConversionResults(int16_t *value)
383 {
384 ads1015Error_t error = ADS1015_ERROR_OK;
385
386 if (!(_ads1015Initialised))
387 {
388 ads1015Init();
389 }
390
391 // Wait for the conversion to complete
392 systickDelay(1);
393
394 // Read the conversion results
395 error = ina219Read16(ADS1015_REG_POINTER_CONVERT, value);
396 if (error) return error;
397
398 // Shift results 4-bits to the right
399 *value = *value >> 4;
400
401 return error;
402 }
403
404
405
406
This page took 0.056627 seconds and 5 git commands to generate.