ADC  8.0
Analog to Digital Conversor library for the Teensy 3.1/3.2 microprocessor
settings_defines.h
1 /* Teensy 4, 3.x, LC ADC library
2  * https://github.com/pedvide/ADC
3  * Copyright (c) 2019 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 
31 #ifndef ADC_SETTINGS_H
32 #define ADC_SETTINGS_H
33 
34 #include <Arduino.h>
35 
37 namespace ADC_settings {
38 
39 // Easier names for the boards
40 #if defined(__MK20DX256__) // Teensy 3.1/3.2
41 #define ADC_TEENSY_3_1
42 #elif defined(__MK20DX128__) // Teensy 3.0
43 #define ADC_TEENSY_3_0
44 #elif defined(__MKL26Z64__) // Teensy LC
45 #define ADC_TEENSY_LC
46 #elif defined(__MK64FX512__) // Teensy 3.5
47 #define ADC_TEENSY_3_5
48 #elif defined(__MK66FX1M0__) // Teensy 3.6
49 #define ADC_TEENSY_3_6
50 #elif defined(__IMXRT1062__) // Teensy 4.0
51 #define ADC_TEENSY_4
52 #else
53 #error "Board not supported!"
54 #endif
55 
56 // Teensy 3.1 has 2 ADCs, Teensy 3.0 and LC only 1.
57 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
58  #define ADC_NUM_ADCS (2)
59  #define ADC_DUAL_ADCS
60 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
61  #define ADC_NUM_ADCS (1)
62  #define ADC_SINGLE_ADC
63 #elif defined(ADC_TEENSY_LC) // Teensy LC
64  #define ADC_NUM_ADCS (1)
65  #define ADC_SINGLE_ADC
66 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
67  #define ADC_NUM_ADCS (2)
68  #define ADC_DUAL_ADCS
69 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
70  #define ADC_NUM_ADCS (2)
71  #define ADC_DUAL_ADCS
72 #elif defined(ADC_TEENSY_4) // Teensy 3.6
73  #define ADC_NUM_ADCS (2)
74  #define ADC_DUAL_ADCS
75 #endif
76 
77 // Use DMA?
78 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
79  #define ADC_USE_DMA
80 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
81  #define ADC_USE_DMA
82 #elif defined(ADC_TEENSY_LC) // Teensy LC
83  #define ADC_USE_DMA
84 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
85  #define ADC_USE_DMA
86 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
87  #define ADC_USE_DMA
88 #elif defined(ADC_TEENSY_4) // Teensy 4.0
89  #define ADC_USE_DMA
90 #endif
91 
92 // Use PGA?
93 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
94  #define ADC_USE_PGA
95 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
96 #elif defined(ADC_TEENSY_LC) // Teensy LC
97 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
98 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
99 #elif defined(ADC_TEENSY_4) // Teensy 4
100 #endif
101 
102 // Use PDB?
103 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
104  #define ADC_USE_PDB
105 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
106  #define ADC_USE_PDB
107 #elif defined(ADC_TEENSY_LC) // Teensy LC
108 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
109  #define ADC_USE_PDB
110 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
111  #define ADC_USE_PDB
112 #elif defined(ADC_TEENSY_4) // Teensy 4
113 #endif
114 
115 // Use Quad Timer
116 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
117  #define ADC_USE_QUAD_TIMER // TODO: Not implemented
118 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
119  #define ADC_USE_QUAD_TIMER // TODO: Not implemented
120 #elif defined(ADC_TEENSY_LC) // Teensy LC
121 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
122  #define ADC_USE_QUAD_TIMER // TODO: Not implemented
123 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
124  #define ADC_USE_QUAD_TIMER // TODO: Not implemented
125 #elif defined(ADC_TEENSY_4) // Teensy 4
126  #define ADC_USE_QUAD_TIMER
127 #endif
128 
129 // Has internal reference?
130 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
131  #define ADC_USE_INTERNAL_VREF
132 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
133  #define ADC_USE_INTERNAL_VREF
134 #elif defined(ADC_TEENSY_LC) // Teensy LC
135 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
136  #define ADC_USE_INTERNAL_VREF
137 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
138  #define ADC_USE_INTERNAL_VREF
139 #elif defined(ADC_TEENSY_4) // Teensy 4
140 #endif
141 
144 enum class ADC_REF_SOURCE : uint8_t {REF_DEFAULT = 0, REF_ALT = 1, REF_NONE = 2}; // internal, do not use
146 #if defined(ADC_TEENSY_3_0) || defined(ADC_TEENSY_3_1) || defined(ADC_TEENSY_3_5) || defined(ADC_TEENSY_3_6)
147 // default is the external, that is connected to the 3.3V supply.
148 // To use the external simply connect AREF to a different voltage
149 // alt is connected to the 1.2 V ref.
151 enum class ADC_REFERENCE : uint8_t {
152  REF_3V3 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT),
153  REF_1V2 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_ALT),
154  REF_EXT = static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT),
155  NONE = static_cast<uint8_t>(ADC_REF_SOURCE::REF_NONE) // internal, do not use
156 };
157 #elif defined(ADC_TEENSY_LC)
158 // alt is the internal ref, 3.3 V
159 // the default is AREF
161 enum class ADC_REFERENCE : uint8_t {
162  REF_3V3 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_ALT),
163  REF_EXT = static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT),
164  NONE = static_cast<uint8_t>(ADC_REF_SOURCE::REF_NONE) // internal, do not use
165 };
166 #elif defined(ADC_TEENSY_4)
167 // default is the external, that is connected to the 3.3V supply.
169 enum class ADC_REFERENCE : uint8_t {
170  REF_3V3 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT),
171  NONE = static_cast<uint8_t>(ADC_REF_SOURCE::REF_NONE) // internal, do not use
172 };
173 #endif
174 
175 // max number of pins, size of channel2sc1aADCx
176 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
177  #define ADC_MAX_PIN (43)
178 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
179  #define ADC_MAX_PIN (43)
180 #elif defined(ADC_TEENSY_LC) // Teensy LC
181  #define ADC_MAX_PIN (43)
182 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
183  #define ADC_MAX_PIN (69)
184 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
185  #define ADC_MAX_PIN (67)
186 #elif defined(ADC_TEENSY_4) // Teensy 4
187  #define ADC_MAX_PIN (27)
188 #endif
189 
190 // number of differential pairs PER ADC!
191 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
192  #define ADC_DIFF_PAIRS (2) // normal and with PGA
193 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
194  #define ADC_DIFF_PAIRS (2)
195 #elif defined(ADC_TEENSY_LC) // Teensy LC
196  #define ADC_DIFF_PAIRS (1)
197 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
198  #define ADC_DIFF_PAIRS (1)
199 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
200  #define ADC_DIFF_PAIRS (1)
201 #elif defined(ADC_TEENSY_4) // Teensy 4
202  #define ADC_DIFF_PAIRS (0)
203 #endif
204 
205 
206 // Other things to measure with the ADC that don't use external pins
207 // 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),
208 // 3.3 V for ADC_VREFH and 0.0 V for ADC_VREFL.
209 #if defined(ADC_TEENSY_LC)
210 
212  enum class ADC_INTERNAL_SOURCE : uint8_t{
213  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
214  BANDGAP = 41, // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see VREF.h)
215  VREFH = 42,
216  VREFL = 43,
217  };
218 #elif defined(ADC_TEENSY_3_1) || defined(ADC_TEENSY_3_0)
219 
221  enum class ADC_INTERNAL_SOURCE : uint8_t{
222  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
223  VREF_OUT = 39,
224  BANDGAP = 41, // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see VREF.h)
225  VREFH = 42,
226  VREFL = 43,
227  };
228 #elif defined(ADC_TEENSY_3_5) || defined(ADC_TEENSY_3_6)
229 
231  enum class ADC_INTERNAL_SOURCE : uint8_t{
232  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
233  VREF_OUT = 28, // only on ADC1
234  BANDGAP = 25, // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see VREF::start in VREF.h)
235  VREFH = 26,
236  VREFL = 27,
237  };
238 #elif defined(ADC_TEENSY_4)
239 
241  enum class ADC_INTERNAL_SOURCE : uint8_t{
242  VREFSH = 25,
243  };
244 #endif
245 
248 #if defined(ADC_TEENSY_4)
249 typedef struct {
250  volatile uint32_t HC0;
251  volatile uint32_t HC1;
252  volatile uint32_t HC2;
253  volatile uint32_t HC3;
254  volatile uint32_t HC4;
255  volatile uint32_t HC5;
256  volatile uint32_t HC6;
257  volatile uint32_t HC7;
258  volatile uint32_t HS;
259  volatile uint32_t R0;
260  volatile uint32_t R1;
261  volatile uint32_t R2;
262  volatile uint32_t R3;
263  volatile uint32_t R4;
264  volatile uint32_t R5;
265  volatile uint32_t R6;
266  volatile uint32_t R7;
267  volatile uint32_t CFG;
268  volatile uint32_t GC;
269  volatile uint32_t GS;
270  volatile uint32_t CV;
271  volatile uint32_t OFS;
272  volatile uint32_t CAL;
273 } ADC_REGS_t;
274 #define ADC0_START (*(ADC_REGS_t *)0x400C4000)
275 #define ADC1_START (*(ADC_REGS_t *)0x400C8000)
276 #else
277 typedef struct {
278  volatile uint32_t SC1A;
279  volatile uint32_t SC1B;
280  volatile uint32_t CFG1;
281  volatile uint32_t CFG2;
282  volatile uint32_t RA;
283  volatile uint32_t RB;
284  volatile uint32_t CV1;
285  volatile uint32_t CV2;
286  volatile uint32_t SC2;
287  volatile uint32_t SC3;
288  volatile uint32_t OFS;
289  volatile uint32_t PG;
290  volatile uint32_t MG;
291  volatile uint32_t CLPD;
292  volatile uint32_t CLPS;
293  volatile uint32_t CLP4;
294  volatile uint32_t CLP3;
295  volatile uint32_t CLP2;
296  volatile uint32_t CLP1;
297  volatile uint32_t CLP0;
298  volatile uint32_t PGA;
299  volatile uint32_t CLMD;
300  volatile uint32_t CLMS;
301  volatile uint32_t CLM4;
302  volatile uint32_t CLM3;
303  volatile uint32_t CLM2;
304  volatile uint32_t CLM1;
305  volatile uint32_t CLM0;
306 } ADC_REGS_t;
307 #define ADC0_START (*(ADC_REGS_t *)0x4003B000)
308 #define ADC1_START (*(ADC_REGS_t *)0x400BB000)
309 #endif
310 
312 
313 /* MK20DX256 Datasheet:
314 The 16-bit accuracy specifications listed in Table 24 and Table 25 are achievable on the
315 differential pins ADCx_DP0, ADCx_DM0
316 All other ADC channels meet the 13-bit differential/12-bit single-ended accuracy
317 specifications.
318 
319 The results in this data sheet were derived from a system which has < 8 Ohm analog source resistance. The RAS/CAS
320 time constant should be kept to < 1ns.
321 
322 ADC clock should be 2 to 12 MHz for 16 bit mode
323 ADC clock should be 1 to 18 MHz for 8-12 bit mode, and 1-24 MHz for Teensy 3.6 (NOT 3.5)
324 To use the maximum ADC conversion clock frequency, the ADHSC bit must be set and the ADLPC bit must be clear
325 
326 The ADHSC bit is used to configure a higher clock input frequency. This will allow
327 faster overall conversion times. To meet internal ADC timing requirements, the ADHSC
328 bit adds additional ADCK cycles. Conversions with ADHSC = 1 take two more ADCK
329 cycles. ADHSC should be used when the ADCLK exceeds the limit for ADHSC = 0.
330 
331 */
332 // the alternate clock is connected to OSCERCLK (16 MHz).
333 // datasheet says ADC clock should be 2 to 12 MHz for 16 bit mode
334 // 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)
335 // calibration works best when averages are 32 and speed is less than 4 MHz
336 // ADC_CFG1_ADICLK: 0=bus, 1=bus/2, 2=(alternative clk) altclk, 3=(async. clk) adack
337 // See below for an explanation of VERY_LOW_SPEED, LOW_SPEED, etc.
338 
339 #define ADC_MHz (1000000) // not so many zeros
340 // Min freq for 8-12 bit mode is 1 MHz, 4 MHz for Teensy 4
341 #if defined(ADC_TEENSY_4)
342  #define ADC_MIN_FREQ (4*ADC_MHz)
343 #else
344  #define ADC_MIN_FREQ (1*ADC_MHz)
345 #endif
346 // Max freq for 8-12 bit mode is 18 MHz, 24 MHz for Teensy 3.6, and 40 for Teensy 4
347 #if defined(ADC_TEENSY_3_6)
348  #define ADC_MAX_FREQ (24*ADC_MHz)
349 #elif defined(ADC_TEENSY_4)
350  #define ADC_MAX_FREQ (40*ADC_MHz)
351 #else
352  #define ADC_MAX_FREQ (18*ADC_MHz)
353 #endif
354 
355 // Min and max for 16 bits. For Teensy 4 is the same as before (no 16 bit mode)
356 #if defined(ADC_TEENSY_4)
357  #define ADC_MIN_FREQ_16BITS ADC_MIN_FREQ
358  #define ADC_MAX_FREQ_16BITS ADC_MAX_FREQ
359 #else
360  // Min freq for 16 bit mode is 2 MHz
361  #define ADC_MIN_FREQ_16BITS (2*ADC_MHz)
362  // Max freq for 16 bit mode is 12 MHz
363  #define ADC_MAX_FREQ_16BITS (12*ADC_MHz)
364 #endif
365 
366 // We can divide F_BUS by 1, 2, 4, 8, or 16:
367 /*
368 Divide by ADC_CFG1_ADIV ADC_CFG1_ADICLK TOTAL VALUE
369 1 0 0 0 0x00
370 2 1 0 1 0x20
371 4 2 0 2 0x40
372 8 3 0 3 0x60
373 16 3 1 4 0x61
374 (Other combinations are possible)
375 */
376 
377 // Redefine from kinetis.h to remove (uint32_t) casts that the preprocessor doesn't understand
378 // so we can do arithmetic with them when defining ADC_CFG1_MED_SPEED
379 #define ADC_LIB_CFG1_ADIV(n) (((n) & 0x03) << 5)
380 #define ADC_LIB_CFG1_ADICLK(n) (((n) & 0x03) << 0)
381 
382 #if defined(ADC_TEENSY_4)
383  #define ADC_F_BUS F_BUS_ACTUAL // (150*ADC_MHz)
384 #else
385  #define ADC_F_BUS F_BUS
386 #endif
387 
390 constexpr uint32_t get_CFG_VERY_LOW_SPEED(uint32_t f_adc_clock) {
391  if (f_adc_clock/16 >= ADC_MIN_FREQ) {
392  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
393  } else if (f_adc_clock/8 >= ADC_MIN_FREQ){
394  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
395  } else if (f_adc_clock/4 >= ADC_MIN_FREQ) {
396  return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
397  } else if (f_adc_clock/2 >= ADC_MIN_FREQ) {
398  return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
399  } else {
400  return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
401  }
402 }
403 
405 constexpr uint32_t get_CFG_LOW_SPEED(uint32_t f_adc_clock) {
406  if (f_adc_clock/16 >= ADC_MIN_FREQ_16BITS) {
407  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
408  } else if (f_adc_clock/8 >= ADC_MIN_FREQ_16BITS){
409  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
410  } else if (f_adc_clock/4 >= ADC_MIN_FREQ_16BITS) {
411  return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
412  } else if (f_adc_clock/2 >= ADC_MIN_FREQ_16BITS) {
413  return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
414  } else {
415  return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
416  }
417 }
418 
420 constexpr uint32_t get_CFG_HI_SPEED_16_BITS(uint32_t f_adc_clock) {
421  if (f_adc_clock <= ADC_MAX_FREQ_16BITS) {
422  return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
423  } else if (f_adc_clock/2 <= ADC_MAX_FREQ_16BITS){
424  return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
425  } else if (f_adc_clock/4 <= ADC_MAX_FREQ_16BITS) {
426  return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
427  } else if (f_adc_clock/8 <= ADC_MAX_FREQ_16BITS) {
428  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
429  } else {
430  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
431  }
432 }
433 
435 // ADC_CFG1_LOW_SPEED and ADC_CFG1_HI_SPEED_16_BITS @internal
436 constexpr uint32_t get_CFG_MEDIUM_SPEED(uint32_t f_adc_clock) {
437  uint32_t ADC_CFG1_LOW_SPEED = get_CFG_LOW_SPEED(f_adc_clock);
438  uint32_t ADC_CFG1_HI_SPEED_16_BITS = get_CFG_HI_SPEED_16_BITS(f_adc_clock);
439  if (ADC_CFG1_LOW_SPEED - ADC_CFG1_HI_SPEED_16_BITS > 0x20) {
440  return ADC_CFG1_HI_SPEED_16_BITS + 0x20;
441  } else {
442  return ADC_CFG1_HI_SPEED_16_BITS;
443  }
444 
445 }
446 
448 constexpr uint32_t get_CFG_HIGH_SPEED(uint32_t f_adc_clock) {
449  if (f_adc_clock <= ADC_MAX_FREQ) {
450  return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
451  } else if (f_adc_clock/2 <= ADC_MAX_FREQ){
452  return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
453  } else if (f_adc_clock/4 <= ADC_MAX_FREQ) {
454  return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
455  } else if (f_adc_clock/8 <= ADC_MAX_FREQ) {
456  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
457  } else {
458  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
459  }
460 }
461 
463 // but not more than ADC_VERY_HIGH_SPEED_FACTOR*ADC_MAX_FREQ
464 constexpr uint32_t get_CFG_VERY_HIGH_SPEED(uint32_t f_adc_clock) {
465  const uint8_t speed_factor = 2;
466  if (f_adc_clock <= speed_factor*ADC_MAX_FREQ) {
467  return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
468  } else if (f_adc_clock/2 <= speed_factor*ADC_MAX_FREQ){
469  return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
470  } else if (f_adc_clock/4 <= speed_factor*ADC_MAX_FREQ) {
471  return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
472  } else if (f_adc_clock/8 <= speed_factor*ADC_MAX_FREQ) {
473  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
474  } else {
475  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
476  }
477 }
479 
480 
481 // Settings for the power/speed of conversions/sampling
487 enum class ADC_CONVERSION_SPEED : uint8_t {
488 #if defined(ADC_TEENSY_4)
489  VERY_LOW_SPEED, /* Same as LOW_SPEED, here for compatibility*/
491  MED_SPEED,
492  HIGH_SPEED,
493  VERY_HIGH_SPEED = HIGH_SPEED, /* Same as HIGH_SPEED, here for compatibility*/
494 
495  ADACK_10,
496  ADACK_20
497 #else
499  LOW_SPEED,
500  MED_SPEED,
502  HIGH_SPEED,
505  ADACK_2_4,
506  ADACK_4_0,
507  ADACK_5_2,
508  ADACK_6_2
509 #endif
510 };
514 enum class ADC_SAMPLING_SPEED : uint8_t {
515  #if defined(ADC_TEENSY_4)
517  LOW_SPEED,
518  LOW_MED_SPEED,
519  MED_SPEED,
520  MED_HIGH_SPEED,
521  HIGH_SPEED,
522  HIGH_VERY_HIGH_SPEED,
524  #else
526  LOW_SPEED,
527  MED_SPEED,
528  HIGH_SPEED,
530  #endif
531 };
532 
533 
534 
535 // Mask for the channel selection in ADCx_SC1A,
536 // useful if you want to get the channel number from ADCx_SC1A
537 #define ADC_SC1A_CHANNELS (0x1F)
538 // 0x1F=31 in the channel2sc1aADCx means the pin doesn't belong to the ADC module
539 #define ADC_SC1A_PIN_INVALID (0x1F)
540 // Muxsel mask, pins in channel2sc1aADCx with bit 7 set use mux A.
541 #define ADC_SC1A_PIN_MUX (0x80)
542 // Differential pin mask, pins in channel2sc1aADCx with bit 6 set are differential pins.
543 #define ADC_SC1A_PIN_DIFF (0x40)
544 // PGA mask. The pins can use PGA on that ADC
545 #define ADC_SC1A_PIN_PGA (0x80)
546 
547 
548 // Error codes for analogRead and analogReadDifferential
549 #define ADC_ERROR_DIFF_VALUE (-70000)
550 #define ADC_ERROR_VALUE ADC_ERROR_DIFF_VALUE
551 
552 } // namespace settings
553 
558 namespace ADC_Error {
560 
562 
566  enum class ADC_ERROR : uint16_t {
567  OTHER = 1<<0,
568  CALIB = 1<<1,
569  WRONG_PIN = 1<<2,
570  ANALOG_READ = 1<<3,
571  ANALOG_DIFF_READ = 1<<4,
572  CONT = 1<<5,
573  CONT_DIFF = 1<<6,
574  COMPARISON = 1<<7,
575  WRONG_ADC = 1<<8,
576  SYNCH = 1<<9,
578  CLEAR = 0,
579  };
582  inline constexpr ADC_ERROR operator|(ADC_ERROR lhs, ADC_ERROR rhs) {
583  return static_cast<ADC_ERROR> (static_cast<uint16_t>(lhs) | static_cast<uint16_t>(rhs));
584  }
586  inline constexpr ADC_ERROR operator&(ADC_ERROR lhs, ADC_ERROR rhs) {
587  return static_cast<ADC_ERROR> (static_cast<uint16_t>(lhs) & static_cast<uint16_t>(rhs));
588  }
590  inline ADC_ERROR operator|=(volatile ADC_ERROR& lhs, ADC_ERROR rhs) {
591  return lhs = static_cast<ADC_ERROR> (static_cast<uint16_t>(lhs) | static_cast<uint16_t>(rhs));
592  }
594  inline ADC_ERROR operator&=(volatile ADC_ERROR& lhs, ADC_ERROR rhs) {
595  return lhs = static_cast<ADC_ERROR> (static_cast<uint16_t>(lhs) & static_cast<uint16_t>(rhs));
596  }
597 
598  // Prints the human-readable error, if any.
599  // Moved to util.h.
600  // inline const char* getError(ADC_ERROR fail_flag)
601 
602 
604  inline void resetError(volatile ADC_ERROR& fail_flag) {
605  fail_flag = ADC_ERROR::CLEAR;
606  }
608 
609 }
610 
611 #endif // ADC_SETTINGS_H
ADC_settings::ADC_INTERNAL_SOURCE::VREFH
@ VREFH
ADC_settings::ADC_CONVERSION_SPEED::ADACK_5_2
@ ADACK_5_2
ADC_settings::ADC_INTERNAL_SOURCE::BANDGAP
@ BANDGAP
ADC_settings::ADC_INTERNAL_SOURCE::VREFL
@ VREFL
ADC_settings::ADC_INTERNAL_SOURCE::VREF_OUT
@ VREF_OUT
ADC_settings::ADC_INTERNAL_SOURCE::TEMP_SENSOR
@ TEMP_SENSOR
ADC_settings::ADC_CONVERSION_SPEED::ADACK_4_0
@ ADACK_4_0
ADC_Error::ADC_ERROR::CLEAR
@ CLEAR
ADC_settings::ADC_CONVERSION_SPEED::ADACK_2_4
@ ADACK_2_4
ADC_settings::ADC_CONVERSION_SPEED::LOW_SPEED
@ LOW_SPEED
ADC_settings
Board-dependent settings.
Definition: settings_defines.h:37
ADC_settings::ADC_REFERENCE::REF_3V3
@ REF_3V3
ADC_settings::ADC_SAMPLING_SPEED::VERY_HIGH_SPEED
@ VERY_HIGH_SPEED
ADC_settings::ADC_SAMPLING_SPEED::MED_SPEED
@ MED_SPEED
ADC_Error::ADC_ERROR::WRONG_ADC
@ WRONG_ADC
ADC_settings::ADC_CONVERSION_SPEED::VERY_LOW_SPEED
@ VERY_LOW_SPEED
ADC_Error::ADC_ERROR::COMPARISON
@ COMPARISON
ADC_settings::ADC_REFERENCE::REF_1V2
@ REF_1V2
ADC_settings::ADC_SAMPLING_SPEED
ADC_SAMPLING_SPEED
Definition: settings_defines.h:514
ADC_settings::ADC_CONVERSION_SPEED::VERY_HIGH_SPEED
@ VERY_HIGH_SPEED
ADC_settings::ADC_CONVERSION_SPEED::ADACK_6_2
@ ADACK_6_2
ADC_Error::ADC_ERROR::CONT_DIFF
@ CONT_DIFF
ADC_settings::ADC_INTERNAL_SOURCE
ADC_INTERNAL_SOURCE
Definition: settings_defines.h:221
ADC_settings::ADC_CONVERSION_SPEED::HIGH_SPEED
@ HIGH_SPEED
ADC_settings::ADC_CONVERSION_SPEED::MED_SPEED
@ MED_SPEED
ADC_settings::ADC_REFERENCE::REF_EXT
@ REF_EXT
ADC_Error::ADC_ERROR
ADC_ERROR
ADC errors.
Definition: settings_defines.h:566
ADC_Error::ADC_ERROR::SYNCH
@ SYNCH
ADC_settings::ADC_SAMPLING_SPEED::VERY_LOW_SPEED
@ VERY_LOW_SPEED
ADC_settings::ADC_SAMPLING_SPEED::LOW_SPEED
@ LOW_SPEED
ADC_Error
Handle ADC errors.
Definition: settings_defines.h:559
ADC_Error::ADC_ERROR::CALIB
@ CALIB
ADC_settings::ADC_SAMPLING_SPEED::HIGH_SPEED
@ HIGH_SPEED
ADC_settings::ADC_REFERENCE
ADC_REFERENCE
Voltage reference for the ADC.
Definition: settings_defines.h:151
ADC_Error::ADC_ERROR::ANALOG_READ
@ ANALOG_READ
ADC_Error::ADC_ERROR::CONT
@ CONT
ADC_Error::ADC_ERROR::OTHER
@ OTHER
ADC_Error::ADC_ERROR::WRONG_PIN
@ WRONG_PIN
ADC_settings::ADC_CONVERSION_SPEED::HIGH_SPEED_16BITS
@ HIGH_SPEED_16BITS
ADC_settings::ADC_CONVERSION_SPEED
ADC_CONVERSION_SPEED
Definition: settings_defines.h:487
ADC_Error::ADC_ERROR::ANALOG_DIFF_READ
@ ANALOG_DIFF_READ