ADC  8.0
ADC_Module.h
Go to the documentation of this file.
1 /* Teensy 3.x, LC ADC library
2  * https://github.com/pedvide/ADC
3  * Copyright (c) 2017 Pedro Villanueva
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25 
26 /* ADC_Module.h: Declarations of the fuctions of a Teensy 3.x, LC ADC module
27  *
28  */
29 
30 
31 #ifndef ADC_MODULE_H
32 #define ADC_MODULE_H
33 
34 #include <Arduino.h>
35 
36 #include <atomic.h>
37 
38 // Easier names for the boards
39 #if defined(__MK20DX256__) // Teensy 3.1
40 #define ADC_TEENSY_3_1
41 #elif defined(__MK20DX128__) // Teensy 3.0
42 #define ADC_TEENSY_3_0
43 #elif defined(__MKL26Z64__) // Teensy LC
44 #define ADC_TEENSY_LC
45 #elif defined(__MK64FX512__) // Teensy 3.5
46 #define ADC_TEENSY_3_5
47 #elif defined(__MK66FX1M0__) // Teensy 3.6
48 #define ADC_TEENSY_3_6
49 #else
50 #error "Board not supported!"
51 #endif
52 
53 
54 
55 // Teensy 3.1 has 2 ADCs, Teensy 3.0 and LC only 1.
56 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
57  #define ADC_NUM_ADCS (2)
58 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
59  #define ADC_NUM_ADCS (1)
60 #elif defined(ADC_TEENSY_LC) // Teensy LC
61  #define ADC_NUM_ADCS (1)
62 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
63  #define ADC_NUM_ADCS (2)
64 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
65  #define ADC_NUM_ADCS (2)
66 #endif
67 
68 // Use DMA?
69 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
70  #define ADC_USE_DMA (1)
71 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
72  #define ADC_USE_DMA (1)
73 #elif defined(ADC_TEENSY_LC) // Teensy LC
74  #define ADC_USE_DMA (1)
75 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
76  #define ADC_USE_DMA (1)
77 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
78  #define ADC_USE_DMA (1)
79 #endif
80 
81 // Use PGA?
82 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
83  #define ADC_USE_PGA (1)
84 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
85  #define ADC_USE_PGA (0)
86 #elif defined(ADC_TEENSY_LC) // Teensy LC
87  #define ADC_USE_PGA (0)
88 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
89  #define ADC_USE_PGA (0)
90 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
91  #define ADC_USE_PGA (0)
92 #endif
93 
94 // Use PDB?
95 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
96  #define ADC_USE_PDB (1)
97 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
98  #define ADC_USE_PDB (1)
99 #elif defined(ADC_TEENSY_LC) // Teensy LC
100  #define ADC_USE_PDB (0)
101 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
102  #define ADC_USE_PDB (1)
103 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
104  #define ADC_USE_PDB (1)
105 #endif
106 
107 // Has internal reference?
108 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
109  #define ADC_USE_INTERNAL_VREF (1)
110 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
111  #define ADC_USE_INTERNAL_VREF (1)
112 #elif defined(ADC_TEENSY_LC) // Teensy LC
113  #define ADC_USE_INTERNAL_VREF (0)
114 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
115  #define ADC_USE_INTERNAL_VREF (1)
116 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
117  #define ADC_USE_INTERNAL_VREF (1)
118 #endif
119 
120 
121 // Select the voltage reference sources for ADC. This is an internal setting, do not use
122 enum class ADC_REF_SOURCE : uint8_t {REF_DEFAULT = 0, REF_ALT = 1, REF_NONE = 2}; // internal, do not use
123 #if defined(ADC_TEENSY_3_0) || defined(ADC_TEENSY_3_1) || defined(ADC_TEENSY_3_5) || defined(ADC_TEENSY_3_6)
124 // default is the external, that is connected to the 3.3V supply.
125 // To use the external simply connect AREF to a different voltage
126 // alt is connected to the 1.2 V ref.
129 enum class ADC_REFERENCE : uint8_t {
130  REF_3V3 = ADC_REF_SOURCE::REF_DEFAULT,
131  REF_1V2 = ADC_REF_SOURCE::REF_ALT,
132  REF_EXT = ADC_REF_SOURCE::REF_DEFAULT,
133  NONE = ADC_REF_SOURCE::REF_NONE // internal, do not use
134 };
135 #elif defined(ADC_TEENSY_LC)
136 // alt is the internal ref, 3.3 V
137 // the default is AREF
140 enum class ADC_REFERENCE : uint8_t {
141  REF_3V3 = ADC_REF_SOURCE::REF_ALT,
142  REF_EXT = ADC_REF_SOURCE::REF_DEFAULT,
143  NONE = ADC_REF_SOURCE::REF_NONE // internal, do not use
144 };
145 #endif
146 
147 // max number of pins, size of channel2sc1aADCx
148 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
149  #define ADC_MAX_PIN (43)
150 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
151  #define ADC_MAX_PIN (43)
152 #elif defined(ADC_TEENSY_LC) // Teensy LC
153  #define ADC_MAX_PIN (43)
154 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
155  #define ADC_MAX_PIN (69)
156 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
157  #define ADC_MAX_PIN (67)
158 #endif
159 
160 
161 // number of differential pairs PER ADC!!
162 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
163  #define ADC_DIFF_PAIRS (2) // normal and with PGA
164 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
165  #define ADC_DIFF_PAIRS (2)
166 #elif defined(ADC_TEENSY_LC) // Teensy LC
167  #define ADC_DIFF_PAIRS (1)
168 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
169  #define ADC_DIFF_PAIRS (1)
170 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
171  #define ADC_DIFF_PAIRS (1)
172 #endif
173 
174 
175 // Other things to measure with the ADC that don't use external pins
176 // In my Teensy I read 1.22 V for the ADC_VREF_OUT (see VREF.h), 1.0V for ADC_BANDGAP (after PMC_REGSC |= PMC_REGSC_BGBE),
177 // 3.3 V for ADC_VREFH and 0.0 V for ADC_VREFL.
178 #if defined(ADC_TEENSY_LC)
179 
181  enum class ADC_INTERNAL_SOURCE : uint8_t{
182  TEMP_SENSOR = 38, // 0.719 V at 25ºC and slope of 1.715 mV/ºC for Teensy 3.x and 0.716 V, 1.62 mV/ºC for Teensy LC
183  BANDGAP = 41, // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see VREF.h)
184  VREFH = 42,
185  VREFL = 43,
186  };
187 #elif defined(ADC_TEENSY_3_1) || defined(ADC_TEENSY_3_0)
188 
190  enum class ADC_INTERNAL_SOURCE : uint8_t{
191  TEMP_SENSOR = 38, // 0.719 V at 25ºC and slope of 1.715 mV/ºC for Teensy 3.x and 0.716 V, 1.62 mV/ºC for Teensy LC
192  VREF_OUT = 39,
193  BANDGAP = 41, // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see VREF.h)
194  VREFH = 42,
195  VREFL = 43,
196  };
197 #elif defined(ADC_TEENSY_3_5) || defined(ADC_TEENSY_3_6)
198 
200  enum class ADC_INTERNAL_SOURCE : uint8_t{
201  TEMP_SENSOR = 24, // 0.719 V at 25ºC and slope of 1.715 mV/ºC for Teensy 3.x and 0.716 V, 1.62 mV/ºC for Teensy LC
202  VREF_OUT = 28, // only on ADC1
203  BANDGAP = 25, // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see VREF::start in VREF.h)
204  VREFH = 26,
205  VREFL = 27,
206  };
207 #endif
208 
209 /* MK20DX256 Datasheet:
210 The 16-bit accuracy specifications listed in Table 24 and Table 25 are achievable on the
211 differential pins ADCx_DP0, ADCx_DM0
212 All other ADC channels meet the 13-bit differential/12-bit single-ended accuracy
213 specifications.
214 
215 The results in this data sheet were derived from a system which has < 8 Ohm analog source resistance. The RAS/CAS
216 time constant should be kept to < 1ns.
217 
218 ADC clock should be 2 to 12 MHz for 16 bit mode
219 ADC clock should be 1 to 18 MHz for 8-12 bit mode, and 1-24 MHz for Teensy 3.6 (NOT 3.5)
220 To use the maximum ADC conversion clock frequency, the ADHSC bit must be set and the ADLPC bit must be clear
221 
222 The ADHSC bit is used to configure a higher clock input frequency. This will allow
223 faster overall conversion times. To meet internal ADC timing requirements, the ADHSC
224 bit adds additional ADCK cycles. Conversions with ADHSC = 1 take two more ADCK
225 cycles. ADHSC should be used when the ADCLK exceeds the limit for ADHSC = 0.
226 
227 */
228 // the alternate clock is connected to OSCERCLK (16 MHz).
229 // datasheet says ADC clock should be 2 to 12 MHz for 16 bit mode
230 // datasheet says ADC clock should be 1 to 18 MHz for 8-12 bit mode, and 1-24 MHz for Teensy 3.6 (NOT 3.5)
231 // calibration works best when averages are 32 and speed is less than 4 MHz
232 // ADC_CFG1_ADICLK: 0=bus, 1=bus/2, 2=(alternative clk) altclk, 3=(async. clk) adack
233 // See below for an explanation of VERY_LOW_SPEED, LOW_SPEED, etc.
234 #if F_BUS == 120000000
235  #define ADC_CFG1_7_5MHZ (ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(1))
236  #define ADC_CFG1_15MHZ (ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1))
237  #define ADC_CFG1_30MHZ (ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1))
238  #define ADC_CFG1_60MHZ (ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1)) // too fast
239 
240  #define ADC_CFG1_VERY_LOW_SPEED ADC_CFG1_LOW_SPEED
241  #define ADC_CFG1_LOW_SPEED (ADC_CFG1_7_5MHZ)
242  #define ADC_CFG1_MED_SPEED (ADC_CFG1_7_5MHZ)
243  #define ADC_CFG1_HI_SPEED_16_BITS (ADC_CFG1_7_5MHZ)
244  #define ADC_CFG1_HI_SPEED (ADC_CFG1_15MHZ)
245  #define ADC_CFG1_VERY_HIGH_SPEED (ADC_CFG1_15MHZ)
246 #elif F_BUS == 108000000
247  #define ADC_CFG1_6_75MHZ (ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(1))
248  #define ADC_CFG1_13_5MHZ (ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1))
249  #define ADC_CFG1_27MHZ (ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1))
250  #define ADC_CFG1_54MHZ (ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1)) // too fast
251 
252  #define ADC_CFG1_VERY_LOW_SPEED ADC_CFG1_LOW_SPEED
253  #define ADC_CFG1_LOW_SPEED (ADC_CFG1_6_75MHZ)
254  #define ADC_CFG1_MED_SPEED (ADC_CFG1_6_75MHZ)
255  #define ADC_CFG1_HI_SPEED_16_BITS (ADC_CFG1_6_75MHZ)
256  #define ADC_CFG1_HI_SPEED (ADC_CFG1_13_5MHZ)
257  #define ADC_CFG1_VERY_HIGH_SPEED (ADC_CFG1_27MHZ)
258 #elif F_BUS == 60000000
259  #define ADC_CFG1_3_75MHZ (ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(1))
260  #define ADC_CFG1_7_5MHZ (ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1))
261  #define ADC_CFG1_15MHZ (ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1))
262 
263  #define ADC_CFG1_VERY_LOW_SPEED ADC_CFG1_LOW_SPEED
264  #define ADC_CFG1_LOW_SPEED (ADC_CFG1_3_75MHZ)
265  #define ADC_CFG1_MED_SPEED (ADC_CFG1_7_5MHZ)
266  #define ADC_CFG1_HI_SPEED_16_BITS (ADC_CFG1_7_5MHZ)
267  #define ADC_CFG1_HI_SPEED (ADC_CFG1_15MHZ)
268  #define ADC_CFG1_VERY_HIGH_SPEED ADC_CFG1_HI_SPEED
269 
270 #elif F_BUS == 56000000 || F_BUS == 54000000 // frequency numbers are good for 56 MHz and slightly smaller for 54 MHz
271  #define ADC_CFG1_3_5MHZ (ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(1))
272  #define ADC_CFG1_7MHZ (ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1))
273  #define ADC_CFG1_14MHZ (ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1))
274  #define ADC_CFG1_28MHZ (ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1)) // too fast
275 
276  #define ADC_CFG1_VERY_LOW_SPEED ADC_CFG1_LOW_SPEED
277  #define ADC_CFG1_LOW_SPEED (ADC_CFG1_3_5MHZ)
278  #define ADC_CFG1_MED_SPEED (ADC_CFG1_7MHZ)
279  #define ADC_CFG1_HI_SPEED_16_BITS (ADC_CFG1_7MHZ)
280  #define ADC_CFG1_HI_SPEED (ADC_CFG1_14MHZ)
281  #define ADC_CFG1_VERY_HIGH_SPEED (ADC_CFG1_28MHZ)
282 
283 #elif F_BUS == 48000000
284  #define ADC_CFG1_3MHZ (ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(1)) // Clock divide select: 3=div8 + Input clock: 1=bus/2
285  #define ADC_CFG1_6MHZ (ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1)) // Clock divide select: 2=div4 + Input clock: 1=bus/2
286  #define ADC_CFG1_12MHZ (ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1)) // Clock divide select: 1=div2 Input clock: 1=bus/2
287  #define ADC_CFG1_24MHZ (ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1)) // this is way too fast, so accuracy is not guaranteed, except for T3.6
288 
289  #define ADC_CFG1_VERY_LOW_SPEED ADC_CFG1_LOW_SPEED
290  #define ADC_CFG1_LOW_SPEED (ADC_CFG1_3MHZ)
291  #define ADC_CFG1_MED_SPEED (ADC_CFG1_6MHZ)
292  #define ADC_CFG1_HI_SPEED_16_BITS (ADC_CFG1_12MHZ)
293  #define ADC_CFG1_HI_SPEED (ADC_CFG1_12MHZ)
294  #define ADC_CFG1_VERY_HIGH_SPEED (ADC_CFG1_24MHZ)
295 
296 #elif F_BUS == 40000000
297  #define ADC_CFG1_2_5MHZ (ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(1))
298  #define ADC_CFG1_5MHZ (ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1))
299  #define ADC_CFG1_10MHZ (ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1))
300  #define ADC_CFG1_20MHZ (ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1)) // too fast, except for T3.5
301 
302  #define ADC_CFG1_VERY_LOW_SPEED ADC_CFG1_LOW_SPEED
303  #define ADC_CFG1_LOW_SPEED (ADC_CFG1_2_5MHZ)
304  #define ADC_CFG1_MED_SPEED (ADC_CFG1_5MHZ)
305  #define ADC_CFG1_HI_SPEED_16_BITS (ADC_CFG1_10MHZ)
306  #define ADC_CFG1_HI_SPEED (ADC_CFG1_10MHZ)
307  #define ADC_CFG1_VERY_HIGH_SPEED (ADC_CFG1_20MHZ)
308 
309 #elif F_BUS == 36000000
310  #define ADC_CFG1_2_25MHZ (ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(1))
311  #define ADC_CFG1_4_5MHZ (ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1))
312  #define ADC_CFG1_9MHZ (ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1))
313  #define ADC_CFG1_18MHZ (ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1))
314 
315  #define ADC_CFG1_VERY_LOW_SPEED (ADC_CFG1_2_25MHZ)
316  #define ADC_CFG1_LOW_SPEED (ADC_CFG1_4_5MHZ)
317  #define ADC_CFG1_MED_SPEED (ADC_CFG1_9MHZ)
318  #define ADC_CFG1_HI_SPEED_16_BITS (ADC_CFG1_9MHZ)
319  #define ADC_CFG1_HI_SPEED (ADC_CFG1_18MHZ)
320  #define ADC_CFG1_VERY_HIGH_SPEED ADC_CFG1_HI_SPEED
321 
322 #elif F_BUS == 24000000
323  #define ADC_CFG1_1_5MHZ (ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(1)) // Clock divide select: 3=div8 + Input clock: 1=bus/2
324  #define ADC_CFG1_3MHZ (ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(0)) // Clock divide select: 3=div8 + Input clock: 0=bus
325  #define ADC_CFG1_6MHZ (ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(0)) // Clock divide select: 2=div4 + Input clock: 0=bus
326  #define ADC_CFG1_12MHZ (ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0)) // Clock divide select: 1=div2 + Input clock: 0=bus
327  #define ADC_CFG1_24MHZ (ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0)) // too fast, except for T3.5
328 
329  #define ADC_CFG1_VERY_LOW_SPEED (ADC_CFG1_1_5MHZ)
330  #define ADC_CFG1_LOW_SPEED (ADC_CFG1_3MHZ)
331  #define ADC_CFG1_MED_SPEED (ADC_CFG1_6MHZ)
332  #define ADC_CFG1_HI_SPEED_16_BITS (ADC_CFG1_12MHZ)
333  #define ADC_CFG1_HI_SPEED (ADC_CFG1_12MHZ)
334  #define ADC_CFG1_VERY_HIGH_SPEED (ADC_CFG1_24MHZ)
335 
336 #elif F_BUS == 4000000
337  #define ADC_CFG1_1MHZ (ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(0))
338  #define ADC_CFG1_2MHZ (ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0))
339  #define ADC_CFG1_4MHZ (ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0))
340 
341  #define ADC_CFG1_VERY_LOW_SPEED (ADC_CFG1_1MHZ)
342  #define ADC_CFG1_LOW_SPEED (ADC_CFG1_2MHZ)
343  #define ADC_CFG1_MED_SPEED (ADC_CFG1_4MHZ)
344  #define ADC_CFG1_HI_SPEED_16_BITS (ADC_CFG1_4MHZ)
345  #define ADC_CFG1_HI_SPEED (ADC_CFG1_4MHZ)
346  #define ADC_CFG1_VERY_HIGH_SPEED ADC_CFG1_HI_SPEED
347 
348 #elif F_BUS == 2000000
349  #define ADC_CFG1_1MHZ (ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0))
350  #define ADC_CFG1_2MHZ (ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0))
351 
352  #define ADC_CFG1_VERY_LOW_SPEED (ADC_CFG1_1MHZ)
353  #define ADC_CFG1_LOW_SPEED (ADC_CFG1_2MHZ)
354  #define ADC_CFG1_MED_SPEED (ADC_CFG1_2MHZ)
355  #define ADC_CFG1_HI_SPEED_16_BITS (ADC_CFG1_2MHZ)
356  #define ADC_CFG1_HI_SPEED (ADC_CFG1_2MHZ)
357  #define ADC_CFG1_VERY_HIGH_SPEED ADC_CFG1_HI_SPEED
358 
359 #else
360 #error "F_BUS must be 108, 60, 56, 54, 48, 40, 36, 24, 4 or 2 MHz"
361 #endif
362 
363 
364 // Settings for the power/speed of conversions/sampling
370 enum class ADC_CONVERSION_SPEED : uint8_t {
372  LOW_SPEED,
373  MED_SPEED,
375  HIGH_SPEED,
379  ADACK_2_4,
380  ADACK_4_0,
381  ADACK_5_2,
382  ADACK_6_2
383 };
387 enum class ADC_SAMPLING_SPEED : uint8_t {
389  LOW_SPEED,
390  MED_SPEED,
391  HIGH_SPEED,
393 };
394 
395 
396 
397 // Mask for the channel selection in ADCx_SC1A,
398 // useful if you want to get the channel number from ADCx_SC1A
399 #define ADC_SC1A_CHANNELS (0x1F)
400 // 0x1F=31 in the channel2sc1aADCx means the pin doesn't belong to the ADC module
401 #define ADC_SC1A_PIN_INVALID (0x1F)
402 // Muxsel mask, pins in channel2sc1aADCx with bit 7 set use mux A.
403 #define ADC_SC1A_PIN_MUX (0x80)
404 // Differential pin mask, pins in channel2sc1aADCx with bit 6 set are differential pins.
405 #define ADC_SC1A_PIN_DIFF (0x40)
406 // PGA mask. The pins can use PGA on that ADC
407 #define ADC_SC1A_PIN_PGA (0x80)
408 
409 
410 // Error codes for analogRead and analogReadDifferential
411 #define ADC_ERROR_DIFF_VALUE (-70000)
412 #define ADC_ERROR_VALUE ADC_ERROR_DIFF_VALUE
413 
415 
418 enum class ADC_ERROR : uint16_t {
419  OTHER = 1<<0,
420  CALIB = 1<<1,
421  WRONG_PIN = 1<<2,
422  ANALOG_READ = 1<<3,
423  ANALOG_DIFF_READ = 1<<4,
424  CONT = 1<<5,
425  CONT_DIFF = 1<<6,
426  COMPARISON = 1<<7,
427  WRONG_ADC = 1<<8,
428  SYNCH = 1<<9,
430  CLEAR = 0,
431 };
433 inline constexpr ADC_ERROR operator|(ADC_ERROR lhs, ADC_ERROR rhs) {
434  return static_cast<ADC_ERROR> (static_cast<uint16_t>(lhs) | static_cast<uint16_t>(rhs));
435 }
437 inline constexpr ADC_ERROR operator&(ADC_ERROR lhs, ADC_ERROR rhs) {
438  return static_cast<ADC_ERROR> (static_cast<uint16_t>(lhs) & static_cast<uint16_t>(rhs));
439 }
441 inline ADC_ERROR operator|=(volatile ADC_ERROR& lhs, ADC_ERROR rhs) {
442  return lhs = static_cast<ADC_ERROR> (static_cast<uint16_t>(lhs) | static_cast<uint16_t>(rhs));
443 }
445 inline ADC_ERROR operator&=(volatile ADC_ERROR& lhs, ADC_ERROR rhs) {
446  return lhs = static_cast<ADC_ERROR> (static_cast<uint16_t>(lhs) & static_cast<uint16_t>(rhs));
447 }
448 
449 
450 // debug mode: blink the led light
451 #define ADC_debug 0
452 
453 // Define masks for settings that need more than one bit
454 #define ADC_CFG1_ADIV_MASK_1 (1<<6)
455 #define ADC_CFG1_ADIV_MASK_0 (1<<5)
456 
457 #define ADC_CFG1_MODE_MASK_1 (1<<3)
458 #define ADC_CFG1_MODE_MASK_0 (1<<2)
459 
460 #define ADC_CFG1_ADICLK_MASK_1 (1<<1)
461 #define ADC_CFG1_ADICLK_MASK_0 (1<<0)
462 
463 #define ADC_CFG2_ADLSTS_MASK_1 (1<<1)
464 #define ADC_CFG2_ADLSTS_MASK_0 (1<<0)
465 
466 #define ADC_SC2_REFSEL_MASK_0 (1<<0)
467 
468 #define ADC_SC3_AVGS_MASK_1 (1<<1)
469 #define ADC_SC3_AVGS_MASK_0 (1<<0)
470 
471 
472 
476 class ADC_Module {
477 
478 public:
479 
481 
483  struct ADC_NLIST {
485  uint8_t pin, sc1a;
486  };
487 
489 
494  ADC_Module(uint8_t ADC_number, const uint8_t* const a_channel2sc1a, const ADC_NLIST* const a_diff_table);
495 
496 
498 
501  void recalibrate();
502 
504  void calibrate();
505 
507  void wait_for_cal();
508 
509 
511 
513 
518  void setReference(ADC_REFERENCE ref_type);
519 
520 
522 
531  void setResolution(uint8_t bits);
532 
534 
537  uint8_t getResolution();
538 
540 
543  uint32_t getMaxValue();
544 
545 
547 
564  void setConversionSpeed(ADC_CONVERSION_SPEED speed);
565 
566 
568 
577  void setSamplingSpeed(ADC_SAMPLING_SPEED speed);
578 
579 
581 
586  void setAveraging(uint8_t num);
587 
588 
590 
593  void enableInterrupts();
594 
596  void disableInterrupts();
597 
598 
600 
603  void enableDMA();
604 
606  void disableDMA();
607 
608 
610 
617  void enableCompare(int16_t compValue, bool greaterThan);
618 
620 
630  void enableCompareRange(int16_t lowerLimit, int16_t upperLimit, bool insideRange, bool inclusive);
631 
633  void disableCompare();
634 
635 
637 
641  void enablePGA(uint8_t gain);
642 
644 
647  uint8_t getPGA();
648 
650  void disablePGA();
651 
652 
654  void continuousMode() __attribute__((always_inline)) {
655  atomic::setBitFlag(ADC_SC3, ADC_SC3_ADCO);
656  }
658  void singleMode() __attribute__((always_inline)) {
659  atomic::clearBitFlag(ADC_SC3, ADC_SC3_ADCO);
660  }
661 
663  void singleEndedMode() __attribute__((always_inline)) {
664  atomic::clearBitFlag(ADC_SC1A, ADC_SC1_DIFF);
665  }
667  void differentialMode() __attribute__((always_inline)) {
668  atomic::setBitFlag(ADC_SC1A, ADC_SC1_DIFF);
669  }
670 
672  void setSoftwareTrigger() __attribute__((always_inline)) {
673  atomic::clearBitFlag(ADC_SC2, ADC_SC2_ADTRG);
674  }
675 
677  void setHardwareTrigger() __attribute__((always_inline)) {
678  atomic::setBitFlag(ADC_SC2, ADC_SC2_ADTRG);
679  }
680 
681 
683 
685 
688  volatile bool isConverting() __attribute__((always_inline)) {
689  //return (ADC_SC2_adact);
690  return atomic::getBitFlag(ADC_SC2, ADC_SC2_ADACT);
691  //return ((ADC_SC2) & ADC_SC2_ADACT) >> 7;
692  }
693 
695 
700  volatile bool isComplete() __attribute__((always_inline)) {
701  //return (ADC_SC1A_coco);
702  return atomic::getBitFlag(ADC_SC1A, ADC_SC1_COCO);
703  //return ((ADC_SC1A) & ADC_SC1_COCO) >> 7;
704  }
705 
707 
710  volatile bool isDifferential() __attribute__((always_inline)) {
711  //return ((ADC_SC1A) & ADC_SC1_DIFF) >> 5;
712  return atomic::getBitFlag(ADC_SC1A, ADC_SC1_DIFF);
713  }
714 
716 
719  volatile bool isContinuous() __attribute__((always_inline)) {
720  //return (ADC_SC3_adco);
721  return atomic::getBitFlag(ADC_SC3, ADC_SC3_ADCO);
722  //return ((ADC_SC3) & ADC_SC3_ADCO) >> 3;
723  }
724 
726 
729  volatile bool isPGAEnabled() __attribute__((always_inline)) {
730  return atomic::getBitFlag(ADC_PGA, ADC_PGA_PGAEN);
731  }
732 
733 
735 
737 
741  bool checkPin(uint8_t pin);
742 
744 
749  bool checkDifferentialPins(uint8_t pinP, uint8_t pinN);
750 
751 
753 
755 
759  void startReadFast(uint8_t pin); // helper method
760 
762 
767  void startDifferentialFast(uint8_t pinP, uint8_t pinN);
768 
769 
771 
773 
779  int analogRead(uint8_t pin);
780 
782 
792  int analogRead(ADC_INTERNAL_SOURCE pin) __attribute__((always_inline)) {
793  return analogRead(static_cast<uint8_t>(pin));
794  }
795 
796 
798 
805  int analogReadDifferential(uint8_t pinP, uint8_t pinN);
806 
807 
809 
811 
816  bool startSingleRead(uint8_t pin);
817 
819 
825  bool startSingleDifferential(uint8_t pinP, uint8_t pinN);
826 
828 
831  int readSingle() __attribute__((always_inline)) {
832  return analogReadContinuous();
833  }
834 
835 
837 
839 
843  bool startContinuous(uint8_t pin);
844 
846 
851  bool startContinuousDifferential(uint8_t pinP, uint8_t pinN);
852 
854 
859  int analogReadContinuous() __attribute__((always_inline)) {
860  return (int16_t)(int32_t)ADC_RA;
861  }
862 
864  void stopContinuous();
865 
866 
869  #if ADC_USE_PDB
870 
871  // software trigger enable PDB PDB interrupt
872  #define ADC_PDB_CONFIG (PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | PDB_SC_PDBIE \
873  | PDB_SC_CONT | PDB_SC_LDMOD(0))
874  // continuous mode load immediately
875 
876  #define PDB_CHnC1_TOS_1 0x0100
877  #define PDB_CHnC1_EN_1 0x01
878 
880 
884  void startPDB(uint32_t freq);
885 
887  void stopPDB();
888 
890  uint32_t getPDBFrequency();
891 
892  #endif
893 
894 
896 
898  struct ADC_Config {
900  uint32_t savedSC1A, savedSC2, savedSC3, savedCFG1, savedCFG2;
901  } adc_config;
902 
904  uint8_t adcWasInUse;
905 
907  void saveConfig(ADC_Config* config) {
908  config->savedSC1A = ADC_SC1A;
909  config->savedCFG1 = ADC_CFG1;
910  config->savedCFG2 = ADC_CFG2;
911  config->savedSC2 = ADC_SC2;
912  config->savedSC3 = ADC_SC3;
913  }
914 
916  void loadConfig(const ADC_Config* config) {
917  ADC_CFG1 = config->savedCFG1;
918  ADC_CFG2 = config->savedCFG2;
919  ADC_SC2 = config->savedSC2;
920  ADC_SC3 = config->savedSC3;
921  ADC_SC1A = config->savedSC1A; // restore last
922  }
923 
924 
927 
928 
930 
933 
935  void printError() {
936  if(fail_flag != ADC_ERROR::CLEAR) {
937  Serial.print("ADC"); Serial.print(ADC_num);
938  Serial.print(" error: ");
939  switch(fail_flag) {
940  case ADC_ERROR::CALIB:
941  Serial.print("Calibration");
942  break;
944  Serial.print("Wrong pin");
945  break;
947  Serial.print("Analog read");
948  break;
950  Serial.print("Comparison");
951  break;
953  Serial.print("Analog differential read");
954  break;
955  case ADC_ERROR::CONT:
956  Serial.print("Continuous read");
957  break;
959  Serial.print("Continuous differential read");
960  break;
962  Serial.print("Wrong ADC");
963  break;
964  case ADC_ERROR::SYNCH:
965  Serial.print("Synchronous");
966  break;
967  case ADC_ERROR::OTHER:
968  case ADC_ERROR::CLEAR: // silence warnings
969  default:
970  Serial.print("Unknown");
971  break;
972  }
973  Serial.println(" error.");
974  }
975  }
976 
978  void resetError() {
979  fail_flag = ADC_ERROR::CLEAR;
980  }
981 
982 
984  const uint8_t ADC_num;
985 
986 
987 private:
988 
989  // is set to 1 when the calibration procedure is taking place
990  uint8_t calibrating;
991 
992  // the first calibration will use 32 averages and lowest speed,
993  // when this calibration is over the averages and speed will be set to default.
994  uint8_t init_calib;
995 
996  // resolution
997  uint8_t analog_res_bits;
998 
999  // maximum value possible 2^res-1
1000  uint32_t analog_max_val;
1001 
1002  // num of averages
1003  uint8_t analog_num_average;
1004 
1005  // reference can be internal or external
1006  ADC_REF_SOURCE analog_reference_internal;
1007 
1008  // value of the pga
1009  uint8_t pga_value;
1010 
1011  // conversion speed
1012  ADC_CONVERSION_SPEED conversion_speed;
1013 
1014  // sampling speed
1015  ADC_SAMPLING_SPEED sampling_speed;
1016 
1017  // translate pin number to SC1A nomenclature
1018  const uint8_t* const channel2sc1a;
1019 
1020  // same for differential pins
1021  const ADC_NLIST* const diff_table;
1022 
1023 
1025  uint8_t getDifferentialPair(uint8_t pin) {
1026  for(uint8_t i=0; i<ADC_DIFF_PAIRS; i++) {
1027  if(diff_table[i].pin == pin) {
1028  return diff_table[i].sc1a;
1029  }
1030  }
1031  return ADC_SC1A_PIN_INVALID;
1032  }
1033 
1034 
1036  void analog_init();
1037 
1038  // registers point to the correct ADC module
1039  typedef volatile uint32_t& reg;
1040 
1041  // registers that control the adc module
1042  reg ADC_SC1A;
1043  reg ADC_SC1B;
1044 
1045  reg ADC_CFG1;
1046 
1047  reg ADC_CFG2;
1048 
1049  reg ADC_RA;
1050  reg ADC_RB;
1051 
1052  reg ADC_CV1;
1053  reg ADC_CV2;
1054 
1055  reg ADC_SC2;
1056  reg ADC_SC3;
1057 
1058  reg ADC_PGA;
1059 
1060  reg ADC_OFS;
1061  reg ADC_PG;
1062  reg ADC_MG;
1063  reg ADC_CLPD;
1064  reg ADC_CLPS;
1065  reg ADC_CLP4;
1066  reg ADC_CLP3;
1067  reg ADC_CLP2;
1068  reg ADC_CLP1;
1069  reg ADC_CLP0;
1070  reg ADC_CLMD;
1071  reg ADC_CLMS;
1072  reg ADC_CLM4;
1073  reg ADC_CLM3;
1074  reg ADC_CLM2;
1075  reg ADC_CLM1;
1076  reg ADC_CLM0;
1077 
1078  reg PDB0_CHnC1; // PDB channel 0 or 1
1079 
1080  const uint8_t IRQ_ADC; // IRQ number will be IRQ_ADC0 or IRQ_ADC1
1081 
1082 
1083 protected:
1084 
1085 
1086 };
1087 
1088 
1089 #endif // ADC_MODULE_H
volatile bool isContinuous()
Is the ADC in continuous mode?
Definition: ADC_Module.h:719
int readSingle()
Reads the analog value of a single conversion.
Definition: ADC_Module.h:831
Dictionary with the differential pins as keys and the SC1A number as values.
Definition: ADC_Module.h:483
void setHardwareTrigger()
Use hardware to trigger the ADC.
Definition: ADC_Module.h:677
ADC_ERROR operator|=(volatile ADC_ERROR &lhs, ADC_ERROR rhs)
|= operator for ADC_ERRORs, it changes the left hand side ADC_ERROR.
Definition: ADC_Module.h:441
uint8_t num_measurements
Number of measurements that the ADC is performing.
Definition: ADC_Module.h:926
uint8_t pin
Pin and corresponding SC1A value.
Definition: ADC_Module.h:485
ADC_SAMPLING_SPEED
Definition: ADC_Module.h:387
uint32_t savedSC1A
ADC registers.
Definition: ADC_Module.h:900
volatile bool isConverting()
Is the ADC converting at the moment?
Definition: ADC_Module.h:688
Definition: ADC_Module.h:476
volatile ADC_ERROR fail_flag
This flag indicates that some kind of error took place.
Definition: ADC_Module.h:932
ADC_ERROR
ADC errors.
Definition: ADC_Module.h:418
volatile bool isPGAEnabled()
Is the PGA function enabled?
Definition: ADC_Module.h:729
ADC_INTERNAL_SOURCE
Definition: ADC_Module.h:190
void resetError()
Resets all errors from the ADC, if any.
Definition: ADC_Module.h:978
void singleMode()
Set single-shot conversion mode.
Definition: ADC_Module.h:658
int analogRead(ADC_INTERNAL_SOURCE pin)
Returns the analog value of the special internal source, such as the temperature sensor.
Definition: ADC_Module.h:792
void continuousMode()
Set continuous conversion mode.
Definition: ADC_Module.h:654
ADC_CONVERSION_SPEED
Definition: ADC_Module.h:370
void differentialMode()
Set differential conversion mode.
Definition: ADC_Module.h:667
constexpr ADC_ERROR operator|(ADC_ERROR lhs, ADC_ERROR rhs)
OR operator for ADC_ERRORs.
Definition: ADC_Module.h:433
volatile bool isComplete()
Is an ADC conversion ready?
Definition: ADC_Module.h:700
const uint8_t ADC_num
Which adc is this?
Definition: ADC_Module.h:984
void setSoftwareTrigger()
Use software to trigger the ADC, this is the most common setting.
Definition: ADC_Module.h:672
Store the config of the adc.
Definition: ADC_Module.h:898
void saveConfig(ADC_Config *config)
Save config of the ADC to the ADC_Config struct.
Definition: ADC_Module.h:907
void singleEndedMode()
Set single-ended conversion mode.
Definition: ADC_Module.h:663
volatile bool isDifferential()
Is the ADC in differential mode?
Definition: ADC_Module.h:710
ADC_ERROR operator&=(volatile ADC_ERROR &lhs, ADC_ERROR rhs)
&= operator for ADC_ERRORs, it changes the left hand side ADC_ERROR.
Definition: ADC_Module.h:445
uint8_t adcWasInUse
Was the adc in use before a call?
Definition: ADC_Module.h:904
ADC_REFERENCE
Definition: ADC_Module.h:129
void loadConfig(const ADC_Config *config)
Load config to the ADC.
Definition: ADC_Module.h:916
constexpr ADC_ERROR operator&(ADC_ERROR lhs, ADC_ERROR rhs)
AND operator for ADC_ERRORs.
Definition: ADC_Module.h:437
int analogReadContinuous()
Reads the analog value of a continuous conversion.
Definition: ADC_Module.h:859
void printError()
Prints the human-readable error, if any.
Definition: ADC_Module.h:935