PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 3 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  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. /*! \page settings ADC Settings
  26. Board-dependent settings.
  27. See the namespace ADC_settings for all functions.
  28. */
  29. #ifndef ADC_SETTINGS_H
  30. #define ADC_SETTINGS_H
  31. #include <Arduino.h>
  32. //! Board-dependent settings
  33. namespace ADC_settings
  34. {
  35. // Easier names for the boards
  36. #if defined(__MK20DX256__) // Teensy 3.1/3.2
  37. #define ADC_TEENSY_3_1
  38. #elif defined(__MK20DX128__) // Teensy 3.0
  39. #define ADC_TEENSY_3_0
  40. #elif defined(__MKL26Z64__) // Teensy LC
  41. #define ADC_TEENSY_LC
  42. #elif defined(__MK64FX512__) // Teensy 3.5
  43. #define ADC_TEENSY_3_5
  44. #elif defined(__MK66FX1M0__) // Teensy 3.6
  45. #define ADC_TEENSY_3_6
  46. #elif defined(__IMXRT1062__) // Teensy 4.0/4.1
  47. // They only differ in the number of exposed pins
  48. #define ADC_TEENSY_4
  49. #ifdef ARDUINO_TEENSY41
  50. #define ADC_TEENSY_4_1
  51. #else
  52. #define ADC_TEENSY_4_0
  53. #endif
  54. #else
  55. #error "Board not supported!"
  56. #endif
  57. // Teensy 3.1 has 2 ADCs, Teensy 3.0 and LC only 1.
  58. #if defined(ADC_TEENSY_3_1) // Teensy 3.1
  59. #define ADC_NUM_ADCS (2)
  60. #define ADC_DUAL_ADCS
  61. #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
  62. #define ADC_NUM_ADCS (1)
  63. #define ADC_SINGLE_ADC
  64. #elif defined(ADC_TEENSY_LC) // Teensy LC
  65. #define ADC_NUM_ADCS (1)
  66. #define ADC_SINGLE_ADC
  67. #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
  68. #define ADC_NUM_ADCS (2)
  69. #define ADC_DUAL_ADCS
  70. #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
  71. #define ADC_NUM_ADCS (2)
  72. #define ADC_DUAL_ADCS
  73. #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
  74. #define ADC_NUM_ADCS (2)
  75. #define ADC_DUAL_ADCS
  76. #endif
  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, 4.1
  89. #define ADC_USE_DMA
  90. #endif
  91. // Use PGA?
  92. #if defined(ADC_TEENSY_3_1) // Teensy 3.1
  93. #define ADC_USE_PGA
  94. #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
  95. #elif defined(ADC_TEENSY_LC) // Teensy LC
  96. #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
  97. #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
  98. #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
  99. #endif
  100. // Use PDB?
  101. #if defined(ADC_TEENSY_3_1) // Teensy 3.1
  102. #define ADC_USE_PDB
  103. #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
  104. #define ADC_USE_PDB
  105. #elif defined(ADC_TEENSY_LC) // Teensy LC
  106. #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
  107. #define ADC_USE_PDB
  108. #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
  109. #define ADC_USE_PDB
  110. #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
  111. #endif
  112. // Use Quad Timer
  113. #if defined(ADC_TEENSY_3_1) // Teensy 3.1
  114. #define ADC_USE_QUAD_TIMER // TODO: Not implemented
  115. #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
  116. #define ADC_USE_QUAD_TIMER // TODO: Not implemented
  117. #elif defined(ADC_TEENSY_LC) // Teensy LC
  118. #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
  119. #define ADC_USE_QUAD_TIMER // TODO: Not implemented
  120. #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
  121. #define ADC_USE_QUAD_TIMER // TODO: Not implemented
  122. #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
  123. #define ADC_USE_QUAD_TIMER
  124. #endif
  125. // Has a timer?
  126. #if defined(ADC_USE_PDB) || defined(ADC_USE_QUAD_TIMER)
  127. #define ADC_USE_TIMER
  128. #endif
  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, 4.1
  140. #endif
  141. //! \cond internal
  142. //! Select the voltage reference sources for ADC. This is an internal setting, do not use, @internal
  143. enum class ADC_REF_SOURCE : uint8_t
  144. {
  145. REF_DEFAULT = 0,
  146. REF_ALT = 1,
  147. REF_NONE = 2
  148. }; // internal, do not use
  149. //! \endcond
  150. #if defined(ADC_TEENSY_3_0) || defined(ADC_TEENSY_3_1) || defined(ADC_TEENSY_3_5) || defined(ADC_TEENSY_3_6)
  151. // default is the external, that is connected to the 3.3V supply.
  152. // To use the external simply connect AREF to a different voltage
  153. // alt is connected to the 1.2 V ref.
  154. //! Voltage reference for the ADC
  155. enum class ADC_REFERENCE : uint8_t
  156. {
  157. REF_3V3 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT), /*!< 3.3 volts */
  158. REF_1V2 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_ALT), /*!< 1.2 volts */
  159. REF_EXT = static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT), /*!< External VREF */
  160. NONE = static_cast<uint8_t>(ADC_REF_SOURCE::REF_NONE) // internal, do not use
  161. };
  162. #elif defined(ADC_TEENSY_LC)
  163. // alt is the internal ref, 3.3 V
  164. // the default is AREF
  165. //! Voltage reference for the ADC
  166. enum class ADC_REFERENCE : uint8_t
  167. {
  168. REF_3V3 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_ALT), /*!< 3.3 volts */
  169. REF_EXT = static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT), /*!< External VREF */
  170. NONE = static_cast<uint8_t>(ADC_REF_SOURCE::REF_NONE) // internal, do not use
  171. };
  172. #elif defined(ADC_TEENSY_4)
  173. // default is the external, that is connected to the 3.3V supply.
  174. //! Voltage reference for the ADC
  175. enum class ADC_REFERENCE : uint8_t
  176. {
  177. REF_3V3 = static_cast<uint8_t>(ADC_REF_SOURCE::REF_DEFAULT), /*!< 3.3 volts */
  178. NONE = static_cast<uint8_t>(ADC_REF_SOURCE::REF_NONE) // internal, do not use
  179. };
  180. #endif
  181. // max number of pins, size of channel2sc1aADCx
  182. #if defined(ADC_TEENSY_3_1) // Teensy 3.1
  183. #define ADC_MAX_PIN (43)
  184. #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
  185. #define ADC_MAX_PIN (43)
  186. #elif defined(ADC_TEENSY_LC) // Teensy LC
  187. #define ADC_MAX_PIN (43)
  188. #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
  189. #define ADC_MAX_PIN (69)
  190. #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
  191. #define ADC_MAX_PIN (67)
  192. #elif defined(ADC_TEENSY_4_0) // Teensy 4
  193. #define ADC_MAX_PIN (27)
  194. #elif defined(ADC_TEENSY_4_1) // Teensy 4
  195. #define ADC_MAX_PIN (41)
  196. #endif
  197. // number of differential pairs PER ADC!
  198. #if defined(ADC_TEENSY_3_1) // Teensy 3.1
  199. #define ADC_DIFF_PAIRS (2) // normal and with PGA
  200. #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
  201. #define ADC_DIFF_PAIRS (2)
  202. #elif defined(ADC_TEENSY_LC) // Teensy LC
  203. #define ADC_DIFF_PAIRS (1)
  204. #elif defined(ADC_TEENSY_3_5) // Teensy 3.5
  205. #define ADC_DIFF_PAIRS (1)
  206. #elif defined(ADC_TEENSY_3_6) // Teensy 3.6
  207. #define ADC_DIFF_PAIRS (1)
  208. #elif defined(ADC_TEENSY_4) // Teensy 4, 4.1
  209. #define ADC_DIFF_PAIRS (0)
  210. #endif
  211. // Other things to measure with the ADC that don't use external pins
  212. // 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),
  213. // 3.3 V for ADC_VREFH and 0.0 V for ADC_VREFL.
  214. #if defined(ADC_TEENSY_LC)
  215. /*! Other ADC sources to measure, such as the temperature sensor.
  216. */
  217. enum class ADC_INTERNAL_SOURCE : uint8_t
  218. {
  219. TEMP_SENSOR = 38,
  220. /*!< Temperature sensor. */ // 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
  221. BANDGAP = 41,
  222. /*!< BANDGAP */ // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see VREF.h)
  223. VREFH = 42, /*!< High VREF */
  224. VREFL = 43, /*!< Low VREF. */
  225. };
  226. #elif defined(ADC_TEENSY_3_1) || defined(ADC_TEENSY_3_0)
  227. /*! Other ADC sources to measure, such as the temperature sensor.
  228. */
  229. enum class ADC_INTERNAL_SOURCE : uint8_t
  230. {
  231. TEMP_SENSOR = 38,
  232. /*!< Temperature sensor. */ // 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 = 39, /*!< 1.2 V reference */
  234. BANDGAP = 41,
  235. /*!< BANDGAP */ // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see VREF.h)
  236. VREFH = 42, /*!< High VREF */
  237. VREFL = 43, /*!< Low VREF. */
  238. };
  239. #elif defined(ADC_TEENSY_3_5) || defined(ADC_TEENSY_3_6)
  240. /*! Other ADC sources to measure, such as the temperature sensor.
  241. */
  242. enum class ADC_INTERNAL_SOURCE : uint8_t
  243. {
  244. TEMP_SENSOR = 24,
  245. /*!< Temperature sensor. */ // 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
  246. VREF_OUT = 28,
  247. /*!< 1.2 V reference */ // only on ADC1
  248. BANDGAP = 25,
  249. /*!< BANDGAP */ // Enable the Bandgap with PMC_REGSC |= PMC_REGSC_BGBE; (see VREF::start in VREF.h)
  250. VREFH = 26, /*!< High VREF */
  251. VREFL = 27, /*!< Low VREF. */
  252. };
  253. #elif defined(ADC_TEENSY_4)
  254. /*! Other ADC sources to measure, such as the temperature sensor.
  255. */
  256. enum class ADC_INTERNAL_SOURCE : uint8_t
  257. {
  258. VREFSH = 25, /*!< internal channel, for ADC self-test, hard connected to VRH internally */
  259. };
  260. #endif
  261. //! \cond internal
  262. //! Struct containing the registers controlling the ADC
  263. #if defined(ADC_TEENSY_4)
  264. typedef struct
  265. {
  266. volatile uint32_t HC0;
  267. volatile uint32_t HC1;
  268. volatile uint32_t HC2;
  269. volatile uint32_t HC3;
  270. volatile uint32_t HC4;
  271. volatile uint32_t HC5;
  272. volatile uint32_t HC6;
  273. volatile uint32_t HC7;
  274. volatile uint32_t HS;
  275. volatile uint32_t R0;
  276. volatile uint32_t R1;
  277. volatile uint32_t R2;
  278. volatile uint32_t R3;
  279. volatile uint32_t R4;
  280. volatile uint32_t R5;
  281. volatile uint32_t R6;
  282. volatile uint32_t R7;
  283. volatile uint32_t CFG;
  284. volatile uint32_t GC;
  285. volatile uint32_t GS;
  286. volatile uint32_t CV;
  287. volatile uint32_t OFS;
  288. volatile uint32_t CAL;
  289. } ADC_REGS_t;
  290. #define ADC0_START (*(ADC_REGS_t *)0x400C4000)
  291. #define ADC1_START (*(ADC_REGS_t *)0x400C8000)
  292. #else
  293. typedef struct
  294. {
  295. volatile uint32_t SC1A;
  296. volatile uint32_t SC1B;
  297. volatile uint32_t CFG1;
  298. volatile uint32_t CFG2;
  299. volatile uint32_t RA;
  300. volatile uint32_t RB;
  301. volatile uint32_t CV1;
  302. volatile uint32_t CV2;
  303. volatile uint32_t SC2;
  304. volatile uint32_t SC3;
  305. volatile uint32_t OFS;
  306. volatile uint32_t PG;
  307. volatile uint32_t MG;
  308. volatile uint32_t CLPD;
  309. volatile uint32_t CLPS;
  310. volatile uint32_t CLP4;
  311. volatile uint32_t CLP3;
  312. volatile uint32_t CLP2;
  313. volatile uint32_t CLP1;
  314. volatile uint32_t CLP0;
  315. volatile uint32_t PGA;
  316. volatile uint32_t CLMD;
  317. volatile uint32_t CLMS;
  318. volatile uint32_t CLM4;
  319. volatile uint32_t CLM3;
  320. volatile uint32_t CLM2;
  321. volatile uint32_t CLM1;
  322. volatile uint32_t CLM0;
  323. } ADC_REGS_t;
  324. #define ADC0_START (*(ADC_REGS_t *)0x4003B000)
  325. #define ADC1_START (*(ADC_REGS_t *)0x400BB000)
  326. #endif
  327. //! \endcond
  328. /* MK20DX256 Datasheet:
  329. The 16-bit accuracy specifications listed in Table 24 and Table 25 are achievable on the
  330. differential pins ADCx_DP0, ADCx_DM0
  331. All other ADC channels meet the 13-bit differential/12-bit single-ended accuracy
  332. specifications.
  333. The results in this data sheet were derived from a system which has < 8 Ohm analog source resistance. The RAS/CAS
  334. time constant should be kept to < 1ns.
  335. ADC clock should be 2 to 12 MHz for 16 bit mode
  336. ADC clock should be 1 to 18 MHz for 8-12 bit mode, and 1-24 MHz for Teensy 3.6 (NOT 3.5)
  337. To use the maximum ADC conversion clock frequency, the ADHSC bit must be set and the ADLPC bit must be clear
  338. The ADHSC bit is used to configure a higher clock input frequency. This will allow
  339. faster overall conversion times. To meet internal ADC timing requirements, the ADHSC
  340. bit adds additional ADCK cycles. Conversions with ADHSC = 1 take two more ADCK
  341. cycles. ADHSC should be used when the ADCLK exceeds the limit for ADHSC = 0.
  342. */
  343. // the alternate clock is connected to OSCERCLK (16 MHz).
  344. // datasheet says ADC clock should be 2 to 12 MHz for 16 bit mode
  345. // 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)
  346. // calibration works best when averages are 32 and speed is less than 4 MHz
  347. // ADC_CFG1_ADICLK: 0=bus, 1=bus/2, 2=(alternative clk) altclk, 3=(async. clk) adack
  348. // See below for an explanation of VERY_LOW_SPEED, LOW_SPEED, etc.
  349. #define ADC_MHz (1000000) // not so many zeros
  350. // Min freq for 8-12 bit mode is 1 MHz, 4 MHz for Teensy 4
  351. #if defined(ADC_TEENSY_4)
  352. #define ADC_MIN_FREQ (4 * ADC_MHz)
  353. #else
  354. #define ADC_MIN_FREQ (1 * ADC_MHz)
  355. #endif
  356. // Max freq for 8-12 bit mode is 18 MHz, 24 MHz for Teensy 3.6, and 40 for Teensy 4
  357. #if defined(ADC_TEENSY_3_6)
  358. #define ADC_MAX_FREQ (24 * ADC_MHz)
  359. #elif defined(ADC_TEENSY_4)
  360. #define ADC_MAX_FREQ (40 * ADC_MHz)
  361. #else
  362. #define ADC_MAX_FREQ (18 * ADC_MHz)
  363. #endif
  364. // Min and max for 16 bits. For Teensy 4 is the same as before (no 16 bit mode)
  365. #if defined(ADC_TEENSY_4)
  366. #define ADC_MIN_FREQ_16BITS ADC_MIN_FREQ
  367. #define ADC_MAX_FREQ_16BITS ADC_MAX_FREQ
  368. #else
  369. // Min freq for 16 bit mode is 2 MHz
  370. #define ADC_MIN_FREQ_16BITS (2 * ADC_MHz)
  371. // Max freq for 16 bit mode is 12 MHz
  372. #define ADC_MAX_FREQ_16BITS (12 * ADC_MHz)
  373. #endif
  374. // We can divide F_BUS by 1, 2, 4, 8, or 16:
  375. /*
  376. Divide by ADC_CFG1_ADIV ADC_CFG1_ADICLK TOTAL VALUE
  377. 1 0 0 0 0x00
  378. 2 1 0 1 0x20
  379. 4 2 0 2 0x40
  380. 8 3 0 3 0x60
  381. 16 3 1 4 0x61
  382. (Other combinations are possible)
  383. */
  384. // Redefine from kinetis.h to remove (uint32_t) casts that the preprocessor doesn't understand
  385. // so we can do arithmetic with them when defining ADC_CFG1_MED_SPEED
  386. #define ADC_LIB_CFG1_ADIV(n) (((n)&0x03) << 5)
  387. #define ADC_LIB_CFG1_ADICLK(n) (((n)&0x03) << 0)
  388. #if defined(ADC_TEENSY_4)
  389. #define ADC_F_BUS F_BUS_ACTUAL // (150*ADC_MHz)
  390. #else
  391. #define ADC_F_BUS F_BUS
  392. #endif
  393. //! \cond internal
  394. //! ADC_CFG1_VERY_LOW_SPEED is the lowest freq @internal
  395. constexpr uint32_t get_CFG_VERY_LOW_SPEED(uint32_t f_adc_clock)
  396. {
  397. if (f_adc_clock / 16 >= ADC_MIN_FREQ)
  398. {
  399. return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
  400. }
  401. else if (f_adc_clock / 8 >= ADC_MIN_FREQ)
  402. {
  403. return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
  404. }
  405. else if (f_adc_clock / 4 >= ADC_MIN_FREQ)
  406. {
  407. return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
  408. }
  409. else if (f_adc_clock / 2 >= ADC_MIN_FREQ)
  410. {
  411. return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
  412. }
  413. else
  414. {
  415. return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
  416. }
  417. }
  418. //! ADC_CFG1_LOW_SPEED is the lowest freq for 16 bits @internal
  419. constexpr uint32_t get_CFG_LOW_SPEED(uint32_t f_adc_clock)
  420. {
  421. if (f_adc_clock / 16 >= ADC_MIN_FREQ_16BITS)
  422. {
  423. return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
  424. }
  425. else if (f_adc_clock / 8 >= ADC_MIN_FREQ_16BITS)
  426. {
  427. return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
  428. }
  429. else if (f_adc_clock / 4 >= ADC_MIN_FREQ_16BITS)
  430. {
  431. return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
  432. }
  433. else if (f_adc_clock / 2 >= ADC_MIN_FREQ_16BITS)
  434. {
  435. return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
  436. }
  437. else
  438. {
  439. return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
  440. }
  441. }
  442. //! ADC_CFG1_HI_SPEED_16_BITS is the highest freq for 16 bits @internal
  443. constexpr uint32_t get_CFG_HI_SPEED_16_BITS(uint32_t f_adc_clock)
  444. {
  445. if (f_adc_clock <= ADC_MAX_FREQ_16BITS)
  446. {
  447. return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
  448. }
  449. else if (f_adc_clock / 2 <= ADC_MAX_FREQ_16BITS)
  450. {
  451. return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
  452. }
  453. else if (f_adc_clock / 4 <= ADC_MAX_FREQ_16BITS)
  454. {
  455. return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
  456. }
  457. else if (f_adc_clock / 8 <= ADC_MAX_FREQ_16BITS)
  458. {
  459. return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
  460. }
  461. else
  462. {
  463. return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
  464. }
  465. }
  466. //! For ADC_CFG1_MED_SPEED the idea is to check if there's an unused setting between
  467. // ADC_CFG1_LOW_SPEED and ADC_CFG1_HI_SPEED_16_BITS @internal
  468. constexpr uint32_t get_CFG_MEDIUM_SPEED(uint32_t f_adc_clock)
  469. {
  470. uint32_t ADC_CFG1_LOW_SPEED = get_CFG_LOW_SPEED(f_adc_clock);
  471. uint32_t ADC_CFG1_HI_SPEED_16_BITS = get_CFG_HI_SPEED_16_BITS(f_adc_clock);
  472. if (ADC_CFG1_LOW_SPEED - ADC_CFG1_HI_SPEED_16_BITS > 0x20)
  473. {
  474. return ADC_CFG1_HI_SPEED_16_BITS + 0x20;
  475. }
  476. else
  477. {
  478. return ADC_CFG1_HI_SPEED_16_BITS;
  479. }
  480. }
  481. //! ADC_CFG1_HI_SPEED is the highest freq for under 16 bits @internal
  482. constexpr uint32_t get_CFG_HIGH_SPEED(uint32_t f_adc_clock)
  483. {
  484. if (f_adc_clock <= ADC_MAX_FREQ)
  485. {
  486. return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
  487. }
  488. else if (f_adc_clock / 2 <= ADC_MAX_FREQ)
  489. {
  490. return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
  491. }
  492. else if (f_adc_clock / 4 <= ADC_MAX_FREQ)
  493. {
  494. return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
  495. }
  496. else if (f_adc_clock / 8 <= ADC_MAX_FREQ)
  497. {
  498. return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
  499. }
  500. else
  501. {
  502. return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
  503. }
  504. }
  505. //! ADC_CFG1_VERY_HIGH_SPEED >= ADC_CFG1_HI_SPEED and may be out of specs, @internal
  506. // but not more than ADC_VERY_HIGH_SPEED_FACTOR*ADC_MAX_FREQ
  507. constexpr uint32_t get_CFG_VERY_HIGH_SPEED(uint32_t f_adc_clock)
  508. {
  509. const uint8_t speed_factor = 2;
  510. if (f_adc_clock <= speed_factor * ADC_MAX_FREQ)
  511. {
  512. return (ADC_LIB_CFG1_ADIV(0) + ADC_LIB_CFG1_ADICLK(0));
  513. }
  514. else if (f_adc_clock / 2 <= speed_factor * ADC_MAX_FREQ)
  515. {
  516. return (ADC_LIB_CFG1_ADIV(1) + ADC_LIB_CFG1_ADICLK(0));
  517. }
  518. else if (f_adc_clock / 4 <= speed_factor * ADC_MAX_FREQ)
  519. {
  520. return (ADC_LIB_CFG1_ADIV(2) + ADC_LIB_CFG1_ADICLK(0));
  521. }
  522. else if (f_adc_clock / 8 <= speed_factor * ADC_MAX_FREQ)
  523. {
  524. return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(0));
  525. }
  526. else
  527. {
  528. return (ADC_LIB_CFG1_ADIV(3) + ADC_LIB_CFG1_ADICLK(1));
  529. }
  530. }
  531. //! \endcond
  532. // Settings for the power/speed of conversions/sampling
  533. /*! ADC conversion speed.
  534. * Common set of options to select the ADC clock speed F_ADCK, which depends on ADC_F_BUS, except for the ADACK_X_Y options that are independent.
  535. * This selection affects the sampling speed too.
  536. * Note: the F_ADCK speed is not equal to the conversion speed; any measurement takes several F_ADCK cycles to complete including the sampling and conversion steps.
  537. */
  538. enum class ADC_CONVERSION_SPEED : uint8_t
  539. {
  540. #if defined(ADC_TEENSY_4)
  541. VERY_LOW_SPEED, /* Same as LOW_SPEED, here for compatibility*/
  542. LOW_SPEED = VERY_LOW_SPEED, /*!< is guaranteed to be the lowest possible speed within specs for all resolutions. */
  543. MED_SPEED, /*!< is always >= LOW_SPEED and <= HIGH_SPEED. */
  544. HIGH_SPEED, /*!< is guaranteed to be the highest possible speed within specs for resolutions */
  545. VERY_HIGH_SPEED = HIGH_SPEED, /* Same as HIGH_SPEED, here for compatibility*/
  546. ADACK_10, /*!< 10 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS) */
  547. ADACK_20 /*!< 20 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS) */
  548. #else
  549. VERY_LOW_SPEED, /*!< is guaranteed to be the lowest possible speed within specs for resolutions less than 16 bits. */
  550. LOW_SPEED, /*!< is guaranteed to be the lowest possible speed within specs for all resolutions. */
  551. MED_SPEED, /*!< is always >= LOW_SPEED and <= HIGH_SPEED. */
  552. HIGH_SPEED_16BITS, /*!< is guaranteed to be the highest possible speed within specs for all resolutions. */
  553. HIGH_SPEED, /*!< is guaranteed to be the highest possible speed within specs for resolutions less than 16 bits. */
  554. VERY_HIGH_SPEED, /*!< may be out of specs */
  555. ADACK_2_4, /*!< 2.4 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS) */
  556. ADACK_4_0, /*!< 4.0 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS) */
  557. ADACK_5_2, /*!< 5.2 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS) */
  558. ADACK_6_2 /*!< 6.2 MHz asynchronous ADC clock (independent of the global clocks F_CPU or F_BUS) */
  559. #endif
  560. };
  561. /*! ADC sampling speed.
  562. * It selects how many ADCK clock cycles to add.
  563. */
  564. enum class ADC_SAMPLING_SPEED : uint8_t
  565. {
  566. #if defined(ADC_TEENSY_4)
  567. VERY_LOW_SPEED, /*!< is the lowest possible sampling speed (+22 ADCK, 24 in total). */
  568. LOW_SPEED, /*!< adds +18 ADCK, 20 in total. */
  569. LOW_MED_SPEED, /*!< adds +14, 16 in total. */
  570. MED_SPEED, /*!< adds +10, 12 in total. */
  571. MED_HIGH_SPEED, /*!< adds +6 ADCK, 8 in total. */
  572. HIGH_SPEED, /*!< adds +4 ADCK, 6 in total. */
  573. HIGH_VERY_HIGH_SPEED, /*!< +2 ADCK, 4 in total */
  574. VERY_HIGH_SPEED, /*!< is the highest possible sampling speed (0 ADCK added, 2 in total). */
  575. #else
  576. VERY_LOW_SPEED, /*!< is the lowest possible sampling speed (+24 ADCK). */
  577. LOW_SPEED, /*!< adds +16 ADCK. */
  578. MED_SPEED, /*!< adds +10 ADCK. */
  579. HIGH_SPEED, /*!< adds +6 ADCK. */
  580. VERY_HIGH_SPEED, /*!< is the highest possible sampling speed (0 ADCK added). */
  581. #endif
  582. };
  583. // Mask for the channel selection in ADCx_SC1A,
  584. // useful if you want to get the channel number from ADCx_SC1A
  585. #define ADC_SC1A_CHANNELS (0x1F)
  586. // 0x1F=31 in the channel2sc1aADCx means the pin doesn't belong to the ADC module
  587. #define ADC_SC1A_PIN_INVALID (0x1F)
  588. // Muxsel mask, pins in channel2sc1aADCx with bit 7 set use mux A.
  589. #define ADC_SC1A_PIN_MUX (0x80)
  590. // Differential pin mask, pins in channel2sc1aADCx with bit 6 set are differential pins.
  591. #define ADC_SC1A_PIN_DIFF (0x40)
  592. // PGA mask. The pins can use PGA on that ADC
  593. #define ADC_SC1A_PIN_PGA (0x80)
  594. // Error codes for analogRead and analogReadDifferential
  595. #define ADC_ERROR_DIFF_VALUE (-70000)
  596. #define ADC_ERROR_VALUE ADC_ERROR_DIFF_VALUE
  597. } // namespace ADC_settings
  598. /*! \page error ADC error codes
  599. Handle ADC errors. See the namespace ADC_Error for all functions.
  600. */
  601. //! Handle ADC errors
  602. namespace ADC_Error
  603. {
  604. //! ADC errors.
  605. /*! Each board has a adc->adX->fail_flag.
  606. * Include ADC_util.h and use getStringADCError to print the errors (if any) in a human-readable form.
  607. * Use adc->adX->resetError() to reset them.
  608. */
  609. enum class ADC_ERROR : uint16_t
  610. {
  611. OTHER = 1 << 0, /*!< Other error not considered below. */
  612. CALIB = 1 << 1, /*!< Calibration error. */
  613. WRONG_PIN = 1 << 2, /*!< A pin was selected that cannot be read by this ADC module. */
  614. ANALOG_READ = 1 << 3, /*!< Error inside the analogRead method. */
  615. ANALOG_DIFF_READ = 1 << 4, /*!< Error inside the analogReadDifferential method. */
  616. CONT = 1 << 5, /*!< Continuous single-ended measurement error. */
  617. CONT_DIFF = 1 << 6, /*!< Continuous differential measurement error. */
  618. COMPARISON = 1 << 7, /*!< Error during the comparison. */
  619. WRONG_ADC = 1 << 8, /*!< A non-existent ADC module was selected. */
  620. SYNCH = 1 << 9, /*!< Error during a synchronized measurement. */
  621. CLEAR = 0, /*!< No error. */
  622. };
  623. //! \cond internal
  624. //! OR operator for ADC_ERRORs. @internal
  625. inline constexpr ADC_ERROR operator|(ADC_ERROR lhs, ADC_ERROR rhs)
  626. {
  627. return static_cast<ADC_ERROR>(static_cast<uint16_t>(lhs) | static_cast<uint16_t>(rhs));
  628. }
  629. //! AND operator for ADC_ERRORs. @internal
  630. inline constexpr ADC_ERROR operator&(ADC_ERROR lhs, ADC_ERROR rhs)
  631. {
  632. return static_cast<ADC_ERROR>(static_cast<uint16_t>(lhs) & static_cast<uint16_t>(rhs));
  633. }
  634. //! |= operator for ADC_ERRORs, it changes the left hand side ADC_ERROR. @internal
  635. inline ADC_ERROR operator|=(volatile ADC_ERROR &lhs, ADC_ERROR rhs)
  636. {
  637. return lhs = static_cast<ADC_ERROR>(static_cast<uint16_t>(lhs) | static_cast<uint16_t>(rhs));
  638. }
  639. //! &= operator for ADC_ERRORs, it changes the left hand side ADC_ERROR. @internal
  640. inline ADC_ERROR operator&=(volatile ADC_ERROR &lhs, ADC_ERROR rhs)
  641. {
  642. return lhs = static_cast<ADC_ERROR>(static_cast<uint16_t>(lhs) & static_cast<uint16_t>(rhs));
  643. }
  644. // Prints the human-readable error, if any.
  645. // Moved to util.h.
  646. // inline const char* getError(ADC_ERROR fail_flag)
  647. //! Resets all errors from the ADC, if any. @internal
  648. inline void resetError(volatile ADC_ERROR &fail_flag)
  649. {
  650. fail_flag = ADC_ERROR::CLEAR;
  651. }
  652. //! \endcond
  653. } // namespace ADC_Error
  654. #endif // ADC_SETTINGS_H