ADC  9.2
Analog to Digital Conversor library for the Teensy 4 microprocessor
settings_defines.h
1 /* Teensy 4.x, 3.x, LC ADC library
2  * https://github.com/pedvide/ADC
3  * Copyright (c) 2020 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 
32 #ifndef ADC_SETTINGS_H
33 #define ADC_SETTINGS_H
34 
35 #include <Arduino.h>
36 
41 namespace ADC_settings {
42 
43 // Easier names for the boards
44 #if defined(__MK20DX256__) // Teensy 3.1/3.2
45 #define ADC_TEENSY_3_1
46 #elif defined(__MK20DX128__) // Teensy 3.0
47 #define ADC_TEENSY_3_0
48 #elif defined(__MKL26Z64__) // Teensy LC
49 #define ADC_TEENSY_LC
50 #elif defined(__MK64FX512__) // Teensy 3.5
51 #define ADC_TEENSY_3_5
52 #elif defined(__MK66FX1M0__) // Teensy 3.6
53 #define ADC_TEENSY_3_6
54 #elif defined(__IMXRT1062__) // Teensy 4.0/4.1
55 // They only differ in the number of exposed pins
56 #define ADC_TEENSY_4
57 #ifdef ARDUINO_TEENSY41
58 #define ADC_TEENSY_4_1
59 #else
60 #define ADC_TEENSY_4_0
61 #endif
62 #else
63 #error "Board not supported!"
64 #endif
65 
66 // Teensy 3.1 has 2 ADCs, Teensy 3.0 and LC only 1.
67 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
68 #define ADC_NUM_ADCS (2)
69 #define ADC_DUAL_ADCS
70 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
71 #define ADC_NUM_ADCS (1)
72 #define ADC_SINGLE_ADC
73 #elif defined(ADC_TEENSY_LC) // Teensy LC
74 #define ADC_NUM_ADCS (1)
75 #define ADC_SINGLE_ADC
76 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
77 #define ADC_NUM_ADCS (2)
78 #define ADC_DUAL_ADCS
79 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
80 #define ADC_NUM_ADCS (2)
81 #define ADC_DUAL_ADCS
82 #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
83 #define ADC_NUM_ADCS (2)
84 #define ADC_DUAL_ADCS
85 #endif
86 
87 // Use DMA?
88 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
89 #define ADC_USE_DMA
90 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
91 #define ADC_USE_DMA
92 #elif defined(ADC_TEENSY_LC) // Teensy LC
93 #define ADC_USE_DMA
94 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
95 #define ADC_USE_DMA
96 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
97 #define ADC_USE_DMA
98 #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
99 #define ADC_USE_DMA
100 #endif
101 
102 // Use PGA?
103 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
104 #define ADC_USE_PGA
105 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
106 #elif defined(ADC_TEENSY_LC) // Teensy LC
107 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
108 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
109 #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
110 #endif
111 
112 // Use PDB?
113 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
114 #define ADC_USE_PDB
115 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
116 #define ADC_USE_PDB
117 #elif defined(ADC_TEENSY_LC) // Teensy LC
118 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
119 #define ADC_USE_PDB
120 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
121 #define ADC_USE_PDB
122 #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
123 #endif
124 
125 // Use Quad Timer
126 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
127 #define ADC_USE_QUAD_TIMER // TODO: Not implemented
128 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
129 #define ADC_USE_QUAD_TIMER // TODO: Not implemented
130 #elif defined(ADC_TEENSY_LC) // Teensy LC
131 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
132 #define ADC_USE_QUAD_TIMER // TODO: Not implemented
133 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
134 #define ADC_USE_QUAD_TIMER // TODO: Not implemented
135 #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
136 #define ADC_USE_QUAD_TIMER
137 #endif
138 
139 // Has a timer?
140 #if defined(ADC_USE_PDB) || defined(ADC_USE_QUAD_TIMER)
141 #define ADC_USE_TIMER
142 #endif
143 
144 // Has internal reference?
145 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
146 #define ADC_USE_INTERNAL_VREF
147 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
148 #define ADC_USE_INTERNAL_VREF
149 #elif defined(ADC_TEENSY_LC) // Teensy LC
150 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
151 #define ADC_USE_INTERNAL_VREF
152 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
153 #define ADC_USE_INTERNAL_VREF
154 #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
155 #endif
156 
158 
162 enum class ADC_REF_SOURCE : uint8_t {
163  REF_DEFAULT = 0,
164  REF_ALT = 1,
165  REF_NONE = 2
166 };
168 
169 #if defined(ADC_TEENSY_3_0) || defined(ADC_TEENSY_3_1) || \
170  defined(ADC_TEENSY_3_5) || defined(ADC_TEENSY_3_6)
171 
178 enum class ADC_REFERENCE : uint8_t {
179  REF_3V3 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT),
180  REF_1V2 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_ALT),
181  REF_EXT =
182  static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT),
183  NONE = static_cast<uint8_t>(
184  ADC_REF_SOURCE::REF_NONE)
185 };
186 #elif defined(ADC_TEENSY_LC)
187 
193 enum class ADC_REFERENCE : uint8_t {
194  REF_3V3 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_ALT),
195  REF_EXT =
196  static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT),
197  NONE = static_cast<uint8_t>(
198  ADC_REF_SOURCE::REF_NONE)
199 };
200 #elif defined(ADC_TEENSY_4)
201 
206 enum class ADC_REFERENCE : uint8_t {
207  REF_3V3 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT),
208  NONE = static_cast<uint8_t>(
209  ADC_REF_SOURCE::REF_NONE)
210 };
211 #endif
212 
213 // max number of pins, size of channel2sc1aADCx
214 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
215 #define ADC_MAX_PIN (43)
216 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
217 #define ADC_MAX_PIN (43)
218 #elif defined(ADC_TEENSY_LC) // Teensy LC
219 #define ADC_MAX_PIN (43)
220 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
221 #define ADC_MAX_PIN (69)
222 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
223 #define ADC_MAX_PIN (67)
224 #elif defined(ADC_TEENSY_4_0) // Teensy 4
225 #define ADC_MAX_PIN (27)
226 #elif defined(ADC_TEENSY_4_1) // Teensy 4
227 #define ADC_MAX_PIN (41)
228 #endif
229 
230 // number of differential pairs PER ADC!
231 #if defined(ADC_TEENSY_3_1) // Teensy 3.1
232 #define ADC_DIFF_PAIRS (2) // normal and with PGA
233 #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
234 #define ADC_DIFF_PAIRS (2)
235 #elif defined(ADC_TEENSY_LC) // Teensy LC
236 #define ADC_DIFF_PAIRS (1)
237 #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
238 #define ADC_DIFF_PAIRS (1)
239 #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
240 #define ADC_DIFF_PAIRS (1)
241 #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
242 #define ADC_DIFF_PAIRS (0)
243 #endif
244 
245 // Other things to measure with the ADC that don't use external pins
246 // In my Teensy I read 1.22 V for the ADC_VREF_OUT (see VREF.h), 1.0V for
247 // ADC_BANDGAP (after PMC_REGSC |= PMC_REGSC_BGBE), 3.3 V for ADC_VREFH and 0.0
248 // V for ADC_VREFL.
249 #if defined(ADC_TEENSY_LC)
250 
253 enum class ADC_INTERNAL_SOURCE : uint8_t {
254  TEMP_SENSOR = 38, // 0.719 V at 25ºC and slope of 1.715 mV/ºC for
256  // Teensy 3.x and 0.716 V, 1.62 mV/ºC for Teensy
257  // LC
258  BANDGAP = 41, // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see
260  // VREF.h)
261  VREFH = 42,
262  VREFL = 43,
263 };
264 #elif defined(ADC_TEENSY_3_1) || defined(ADC_TEENSY_3_0)
265 
268 enum class ADC_INTERNAL_SOURCE : uint8_t {
269  TEMP_SENSOR = 38, // 0.719 V at 25ºC and slope of 1.715 mV/ºC for
271  // Teensy 3.x and 0.716 V, 1.62 mV/ºC for Teensy
272  // LC
273  VREF_OUT = 39,
274  BANDGAP = 41, // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see
276  // VREF.h)
277  VREFH = 42,
278  VREFL = 43,
279 };
280 #elif defined(ADC_TEENSY_3_5) || defined(ADC_TEENSY_3_6)
281 
284 enum class ADC_INTERNAL_SOURCE : uint8_t {
285  TEMP_SENSOR = 24, // 0.719 V at 25ºC and slope of 1.715 mV/ºC for
287  // Teensy 3.x and 0.716 V, 1.62 mV/ºC for Teensy
288  // LC
289  VREF_OUT = 28, // only on ADC1
291  BANDGAP = 25, // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see
293  // VREF::start in VREF.h)
294  VREFH = 26,
295  VREFL = 27,
296 };
297 #elif defined(ADC_TEENSY_4)
298 
301 enum class ADC_INTERNAL_SOURCE : uint8_t {
302  VREFSH = 25,
304 };
305 #endif
306 
308 
312 #if defined(ADC_TEENSY_4)
313 typedef struct {
314  volatile uint32_t HC0;
315  volatile uint32_t HC1;
316  volatile uint32_t HC2;
317  volatile uint32_t HC3;
318  volatile uint32_t HC4;
319  volatile uint32_t HC5;
320  volatile uint32_t HC6;
321  volatile uint32_t HC7;
322  volatile uint32_t HS;
323  volatile uint32_t R0;
324  volatile uint32_t R1;
325  volatile uint32_t R2;
326  volatile uint32_t R3;
327  volatile uint32_t R4;
328  volatile uint32_t R5;
329  volatile uint32_t R6;
330  volatile uint32_t R7;
331  volatile uint32_t CFG;
332  volatile uint32_t GC;
333  volatile uint32_t GS;
334  volatile uint32_t CV;
335  volatile uint32_t OFS;
336  volatile uint32_t CAL;
337 } ADC_REGS_t;
338 #define ADC0_START (*(ADC_REGS_t *)0x400C4000)
339 #define ADC1_START (*(ADC_REGS_t *)0x400C8000)
340 #else
341 typedef struct {
342  volatile uint32_t SC1A;
343  volatile uint32_t SC1B;
344  volatile uint32_t CFG1;
345  volatile uint32_t CFG2;
346  volatile uint32_t RA;
347  volatile uint32_t RB;
348  volatile uint32_t CV1;
349  volatile uint32_t CV2;
350  volatile uint32_t SC2;
351  volatile uint32_t SC3;
352  volatile uint32_t OFS;
353  volatile uint32_t PG;
354  volatile uint32_t MG;
355  volatile uint32_t CLPD;
356  volatile uint32_t CLPS;
357  volatile uint32_t CLP4;
358  volatile uint32_t CLP3;
359  volatile uint32_t CLP2;
360  volatile uint32_t CLP1;
361  volatile uint32_t CLP0;
362  volatile uint32_t PGA;
363  volatile uint32_t CLMD;
364  volatile uint32_t CLMS;
365  volatile uint32_t CLM4;
366  volatile uint32_t CLM3;
367  volatile uint32_t CLM2;
368  volatile uint32_t CLM1;
369  volatile uint32_t CLM0;
370 } ADC_REGS_t;
371 #define ADC0_START (*(ADC_REGS_t *)0x4003B000)
372 #define ADC1_START (*(ADC_REGS_t *)0x400BB000)
373 #endif
374 
376 /* MK20DX256 Datasheet:
377 The 16-bit accuracy specifications listed in Table 24 and Table 25 are
378 achievable on the differential pins ADCx_DP0, ADCx_DM0 All other ADC channels
379 meet the 13-bit differential/12-bit single-ended accuracy specifications.
380 
381 The results in this data sheet were derived from a system which has < 8 Ohm
382 analog source resistance. The RAS/CAS time constant should be kept to < 1ns.
383 
384 ADC clock should be 2 to 12 MHz for 16 bit mode
385 ADC clock should be 1 to 18 MHz for 8-12 bit mode, and 1-24 MHz for Teensy 3.6
386 (NOT 3.5) To use the maximum ADC conversion clock frequency, the ADHSC bit must
387 be set and the ADLPC bit must be clear
388 
389 The ADHSC bit is used to configure a higher clock input frequency. This will
390 allow faster overall conversion times. To meet internal ADC timing requirements,
391 the ADHSC bit adds additional ADCK cycles. Conversions with ADHSC = 1 take two
392 more ADCK cycles. ADHSC should be used when the ADCLK exceeds the limit for
393 ADHSC = 0.
394 
395 */
396 // the alternate clock is connected to OSCERCLK (16 MHz).
397 // datasheet says ADC clock should be 2 to 12 MHz for 16 bit mode
398 // datasheet says ADC clock should be 1 to 18 MHz for 8-12 bit mode, and 1-24
399 // MHz for Teensy 3.6 (NOT 3.5) calibration works best when averages are 32 and
400 // speed is less than 4 MHz ADC_CFG1_ADICLK: 0=bus, 1=bus/2, 2=(alternative clk)
401 // altclk, 3=(async. clk) adack See below for an explanation of VERY_LOW_SPEED,
402 // LOW_SPEED, etc.
403 
404 #define ADC_MHz (1000000) // not so many zeros
405 // Min freq for 8-12 bit mode is 1 MHz, 4 MHz for Teensy 4
406 #if defined(ADC_TEENSY_4)
407 #define ADC_MIN_FREQ (4 * ADC_MHz)
408 #else
409 #define ADC_MIN_FREQ (1 * ADC_MHz)
410 #endif
411 // Max freq for 8-12 bit mode is 18 MHz, 24 MHz for Teensy 3.6, and 40 for
412 // Teensy 4
413 #if defined(ADC_TEENSY_3_6)
414 #define ADC_MAX_FREQ (24 * ADC_MHz)
415 #elif defined(ADC_TEENSY_4)
416 #define ADC_MAX_FREQ (40 * ADC_MHz)
417 #else
418 #define ADC_MAX_FREQ (18 * ADC_MHz)
419 #endif
420 
421 // Min and max for 16 bits. For Teensy 4 is the same as before (no 16 bit mode)
422 #if defined(ADC_TEENSY_4)
423 #define ADC_MIN_FREQ_16BITS ADC_MIN_FREQ
424 #define ADC_MAX_FREQ_16BITS ADC_MAX_FREQ
425 #else
426 // Min freq for 16 bit mode is 2 MHz
427 #define ADC_MIN_FREQ_16BITS (2 * ADC_MHz)
428 // Max freq for 16 bit mode is 12 MHz
429 #define ADC_MAX_FREQ_16BITS (12 * ADC_MHz)
430 #endif
431 
432 // We can divide F_BUS by 1, 2, 4, 8, or 16:
433 /*
434 Divide by ADC_CFG1_ADIV ADC_CFG1_ADICLK TOTAL VALUE
435 1 0 0 0 0x00
436 2 1 0 1 0x20
437 4 2 0 2 0x40
438 8 3 0 3 0x60
439 16 3 1 4 0x61
440 (Other combinations are possible)
441 */
442 
443 // Redefine from kinetis.h to remove (uint32_t) casts that the preprocessor
444 // doesn't understand so we can do arithmetic with them when defining
445 // ADC_CFG1_MED_SPEED
446 #define ADC_LIB_CFG1_ADIV(n) (((n)&0x03) << 5)
447 #define ADC_LIB_CFG1_ADICLK(n) (((n)&0x03) << 0)
448 
449 #if defined(ADC_TEENSY_4)
450 #define ADC_F_BUS F_BUS_ACTUAL // (150*ADC_MHz)
451 #else
452 #define ADC_F_BUS F_BUS
453 #endif
454 
457 constexpr uint32_t get_CFG_VERY_LOW_SPEED(uint32_t f_adc_clock) {
458  if (f_adc_clock / 16 >= ADC_MIN_FREQ) {
459  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
460  } else if (f_adc_clock / 8 >= ADC_MIN_FREQ) {
461  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
462  } else if (f_adc_clock / 4 >= ADC_MIN_FREQ) {
463  return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
464  } else if (f_adc_clock / 2 >= ADC_MIN_FREQ) {
465  return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
466  } else {
467  return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
468  }
469 }
470 
472 constexpr uint32_t get_CFG_LOW_SPEED(uint32_t f_adc_clock) {
473  if (f_adc_clock / 16 >= ADC_MIN_FREQ_16BITS) {
474  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
475  } else if (f_adc_clock / 8 >= ADC_MIN_FREQ_16BITS) {
476  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
477  } else if (f_adc_clock / 4 >= ADC_MIN_FREQ_16BITS) {
478  return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
479  } else if (f_adc_clock / 2 >= ADC_MIN_FREQ_16BITS) {
480  return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
481  } else {
482  return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
483  }
484 }
485 
487 constexpr uint32_t get_CFG_HI_SPEED_16_BITS(uint32_t f_adc_clock) {
488  if (f_adc_clock <= ADC_MAX_FREQ_16BITS) {
489  return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
490  } else if (f_adc_clock / 2 <= ADC_MAX_FREQ_16BITS) {
491  return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
492  } else if (f_adc_clock / 4 <= ADC_MAX_FREQ_16BITS) {
493  return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
494  } else if (f_adc_clock / 8 <= ADC_MAX_FREQ_16BITS) {
495  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
496  } else {
497  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
498  }
499 }
500 
503 // ADC_CFG1_LOW_SPEED and ADC_CFG1_HI_SPEED_16_BITS @internal
504 constexpr uint32_t get_CFG_MEDIUM_SPEED(uint32_t f_adc_clock) {
505  uint32_t ADC_CFG1_LOW_SPEED = get_CFG_LOW_SPEED(f_adc_clock);
506  uint32_t ADC_CFG1_HI_SPEED_16_BITS = get_CFG_HI_SPEED_16_BITS(f_adc_clock);
507  if (ADC_CFG1_LOW_SPEED - ADC_CFG1_HI_SPEED_16_BITS > 0x20) {
508  return ADC_CFG1_HI_SPEED_16_BITS + 0x20;
509  } else {
510  return ADC_CFG1_HI_SPEED_16_BITS;
511  }
512 }
513 
515 constexpr uint32_t get_CFG_HIGH_SPEED(uint32_t f_adc_clock) {
516  if (f_adc_clock <= ADC_MAX_FREQ) {
517  return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
518  } else if (f_adc_clock / 2 <= ADC_MAX_FREQ) {
519  return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
520  } else if (f_adc_clock / 4 <= ADC_MAX_FREQ) {
521  return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
522  } else if (f_adc_clock / 8 <= ADC_MAX_FREQ) {
523  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
524  } else {
525  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
526  }
527 }
528 
531 // but not more than ADC_VERY_HIGH_SPEED_FACTOR*ADC_MAX_FREQ
532 constexpr uint32_t get_CFG_VERY_HIGH_SPEED(uint32_t f_adc_clock) {
533  const uint8_t speed_factor = 2;
534  if (f_adc_clock <= speed_factor * ADC_MAX_FREQ) {
535  return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
536  } else if (f_adc_clock / 2 <= speed_factor * ADC_MAX_FREQ) {
537  return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
538  } else if (f_adc_clock / 4 <= speed_factor * ADC_MAX_FREQ) {
539  return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
540  } else if (f_adc_clock / 8 <= speed_factor * ADC_MAX_FREQ) {
541  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
542  } else {
543  return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
544  }
545 }
547 
548 // Settings for the power/speed of conversions/sampling
562 enum class ADC_CONVERSION_SPEED : uint8_t {
563 #if defined(ADC_TEENSY_4)
564  VERY_LOW_SPEED, /* Same as LOW_SPEED, here for compatibility*/
565  LOW_SPEED = VERY_LOW_SPEED,
567  MED_SPEED,
568  HIGH_SPEED,
570  VERY_HIGH_SPEED = HIGH_SPEED, /* Same as HIGH_SPEED, here for compatibility*/
571 
572  ADACK_10,
574  ADACK_20
576 #else
577  VERY_LOW_SPEED,
579  LOW_SPEED,
581  MED_SPEED,
582  HIGH_SPEED_16BITS,
584  HIGH_SPEED,
586  VERY_HIGH_SPEED,
588  ADACK_2_4,
590  ADACK_4_0,
592  ADACK_5_2,
594  ADACK_6_2
596 #endif
597 };
603 enum class ADC_SAMPLING_SPEED : uint8_t {
604 #if defined(ADC_TEENSY_4)
607  LOW_SPEED,
608  LOW_MED_SPEED,
609  MED_SPEED,
611  HIGH_SPEED,
615 #else
617  LOW_SPEED,
618  MED_SPEED,
619  HIGH_SPEED,
622 #endif
623 };
624 
625 // Mask for the channel selection in ADCx_SC1A,
626 // useful if you want to get the channel number from ADCx_SC1A
627 #define ADC_SC1A_CHANNELS (0x1F)
628 // 0x1F=31 in the channel2sc1aADCx means the pin doesn't belong to the ADC
629 // module
630 #define ADC_SC1A_PIN_INVALID (0x1F)
631 // Muxsel mask, pins in channel2sc1aADCx with bit 7 set use mux A.
632 #define ADC_SC1A_PIN_MUX (0x80)
633 // Differential pin mask, pins in channel2sc1aADCx with bit 6 set are
634 // differential pins.
635 #define ADC_SC1A_PIN_DIFF (0x40)
636 // PGA mask. The pins can use PGA on that ADC
637 #define ADC_SC1A_PIN_PGA (0x80)
638 
639 // Error codes for analogRead and analogReadDifferential
640 #define ADC_ERROR_DIFF_VALUE (-70000)
641 #define ADC_ERROR_VALUE ADC_ERROR_DIFF_VALUE
642 
643 } // namespace ADC_settings
644 
654 namespace ADC_Error {
661 enum class ADC_ERROR : uint16_t {
662  OTHER = 1 << 0,
663  CALIB = 1 << 1,
664  WRONG_PIN =
665  1 << 2,
666  ANALOG_READ = 1 << 3,
668  1 << 4,
669  CONT = 1 << 5,
670  CONT_DIFF = 1 << 6,
671  COMPARISON = 1 << 7,
672  WRONG_ADC = 1 << 8,
673  SYNCH = 1 << 9,
675  CLEAR = 0,
676 };
679 inline constexpr ADC_ERROR operator|(ADC_ERROR lhs, ADC_ERROR rhs) {
680  return static_cast<ADC_ERROR>(static_cast<uint16_t>(lhs) |
681  static_cast<uint16_t>(rhs));
682 }
684 inline constexpr ADC_ERROR operator&(ADC_ERROR lhs, ADC_ERROR rhs) {
685  return static_cast<ADC_ERROR>(static_cast<uint16_t>(lhs) &
686  static_cast<uint16_t>(rhs));
687 }
690 inline ADC_ERROR operator|=(volatile ADC_ERROR &lhs, ADC_ERROR rhs) {
691  return lhs = static_cast<ADC_ERROR>(static_cast<uint16_t>(lhs) |
692  static_cast<uint16_t>(rhs));
693 }
696 inline ADC_ERROR operator&=(volatile ADC_ERROR &lhs, ADC_ERROR rhs) {
697  return lhs = static_cast<ADC_ERROR>(static_cast<uint16_t>(lhs) &
698  static_cast<uint16_t>(rhs));
699 }
700 
701 // Prints the human-readable error, if any.
702 // Moved to util.h.
703 // inline const char* getError(ADC_ERROR fail_flag)
704 
706 inline void resetError(volatile ADC_ERROR &fail_flag) {
707  fail_flag = ADC_ERROR::CLEAR;
708 }
710 
711 } // namespace ADC_Error
712 
713 #endif // ADC_SETTINGS_H
ADC_settings::ADC_SAMPLING_SPEED::LOW_MED_SPEED
@ LOW_MED_SPEED
ADC_Error::ADC_ERROR::CLEAR
@ CLEAR
ADC_settings::ADC_CONVERSION_SPEED::LOW_SPEED
@ LOW_SPEED
ADC_settings
Board-dependent settings.
Definition: settings_defines.h:41
ADC_settings::ADC_REFERENCE::REF_3V3
@ REF_3V3
ADC_settings::ADC_SAMPLING_SPEED::MED_HIGH_SPEED
@ MED_HIGH_SPEED
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_Error::ADC_ERROR::COMPARISON
@ COMPARISON
ADC_settings::ADC_CONVERSION_SPEED::ADACK_20
@ ADACK_20
ADC_settings::ADC_SAMPLING_SPEED
ADC_SAMPLING_SPEED
ADC sampling speed. It selects how many ADCK clock cycles to add.
Definition: settings_defines.h:603
ADC_Error::ADC_ERROR::CONT_DIFF
@ CONT_DIFF
ADC_settings::ADC_INTERNAL_SOURCE
ADC_INTERNAL_SOURCE
Other ADC sources to measure, such as the temperature sensor.
Definition: settings_defines.h:301
ADC_settings::ADC_CONVERSION_SPEED::ADACK_10
@ ADACK_10
ADC_settings::ADC_CONVERSION_SPEED::HIGH_SPEED
@ HIGH_SPEED
ADC_settings::ADC_CONVERSION_SPEED::MED_SPEED
@ MED_SPEED
ADC_Error::ADC_ERROR
ADC_ERROR
ADC errors. Each board has a adc->adX->fail_flag. Include ADC_util.h and use getStringADCError to pri...
Definition: settings_defines.h:661
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:654
ADC_Error::ADC_ERROR::CALIB
@ CALIB
ADC_settings::ADC_SAMPLING_SPEED::HIGH_VERY_HIGH_SPEED
@ HIGH_VERY_HIGH_SPEED
ADC_settings::ADC_SAMPLING_SPEED::HIGH_SPEED
@ HIGH_SPEED
ADC_settings::ADC_REFERENCE
ADC_REFERENCE
Voltage reference for the ADC default is the external, it is connected to the 3.3V supply.
Definition: settings_defines.h:206
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
ADC_CONVERSION_SPEED
ADC conversion speed. Common set of options to select the ADC clock speed F_ADCK, which depends on AD...
Definition: settings_defines.h:562
ADC_settings::ADC_INTERNAL_SOURCE::VREFSH
@ VREFSH
ADC_Error::ADC_ERROR::ANALOG_DIFF_READ
@ ANALOG_DIFF_READ