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.

ADC.cpp 41KB

3 vuotta sitten
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105
  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. /* ADC.cpp: Implements the control of one or more ADC modules of Teensy 3.x, LC
  26. *
  27. */
  28. #include "ADC.h"
  29. // translate pin number to SC1A nomenclature and viceversa
  30. // we need to create this static const arrays so that we can assign the "normal arrays" to the correct one
  31. // depending on which ADC module we will be.
  32. /* channel2sc1aADCx converts a pin number to their value for the SC1A register, for the ADC0 and ADC1
  33. * numbers with +ADC_SC1A_PIN_MUX (128) means those pins use mux a, the rest use mux b.
  34. * numbers with +ADC_SC1A_PIN_DIFF (64) means it's also a differential pin (treated also in the channel2sc1a_diff_ADCx)
  35. * For diff_table_ADCx, +ADC_SC1A_PIN_PGA means the pin can use PGA on that ADC
  36. */
  37. ///////// ADC0
  38. #if defined(ADC_TEENSY_3_0)
  39. const uint8_t ADC::channel2sc1aADC0[] = {
  40. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  41. 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 0, 19, 3, 21, // 0-13, we treat them as A0-A13
  42. 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 (A0-A9)
  43. 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, // 24-33
  44. 0 + ADC_SC1A_PIN_DIFF, 19 + ADC_SC1A_PIN_DIFF, 3 + ADC_SC1A_PIN_DIFF, 21 + ADC_SC1A_PIN_DIFF, // 34-37 (A10-A13)
  45. 26, 22, 23, 27, 29, 30 // 38-43: temp. sensor, VREF_OUT, A14, bandgap, VREFH, VREFL. A14 isn't connected to anything in Teensy 3.0.
  46. };
  47. #elif defined(ADC_TEENSY_3_1) // the only difference with 3.0 is that A13 is not connected to ADC0 and that T3.1 has PGA.
  48. const uint8_t ADC::channel2sc1aADC0[] = {
  49. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  50. 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 0, 19, 3, 31, // 0-13, we treat them as A0-A13
  51. 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 (A0-A9)
  52. 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, // 24-33
  53. 0 + ADC_SC1A_PIN_DIFF, 19 + ADC_SC1A_PIN_DIFF, 3 + ADC_SC1A_PIN_DIFF, 31 + ADC_SC1A_PIN_DIFF, // 34-37 (A10-A13)
  54. 26, 22, 23, 27, 29, 30 // 38-43: temp. sensor, VREF_OUT, A14, bandgap, VREFH, VREFL. A14 isn't connected to anything in Teensy 3.0.
  55. };
  56. #elif defined(ADC_TEENSY_LC)
  57. // Teensy LC
  58. const uint8_t ADC::channel2sc1aADC0[] = {
  59. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  60. 5, 14, 8, 9, 13, 12, 6, 7, 15, 11, 0, 4 + ADC_SC1A_PIN_MUX, 23, 31, // 0-13, we treat them as A0-A12 + A13= doesn't exist
  61. 5, 14, 8, 9, 13, 12, 6, 7, 15, 11, // 14-23 (A0-A9)
  62. 0 + ADC_SC1A_PIN_DIFF, 4 + ADC_SC1A_PIN_MUX + ADC_SC1A_PIN_DIFF, 23, 31, 31, 31, 31, 31, 31, 31, // 24-33 ((A10-A12) + nothing), A11 uses mux a
  63. 31, 31, 31, 31, // 34-37 nothing
  64. 26, 27, 31, 27, 29, 30 // 38-43: temp. sensor, , , bandgap, VREFH, VREFL.
  65. };
  66. #elif defined(ADC_TEENSY_3_5)
  67. const uint8_t ADC::channel2sc1aADC0[] = {
  68. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  69. 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 3, 31, 31, 31, // 0-13, we treat them as A0-A13
  70. 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 (A0-A9)
  71. 26, 27, 29, 30, 31, 31, 31, // 24-30: Temp_Sensor, bandgap, VREFH, VREFL.
  72. 31, 31, 17, 18, // 31-34 A12(ADC1), A13(ADC1), A14, A15
  73. 31, 31, 31, 31, 31, 31, 31, 31, 31, // 35-43
  74. 31, 31, 31, 31, 31, 31, 31, 31, 31, // 44-52
  75. 31, 31, 31, 31, 31, 31, 31, 31, 31, // 53-61
  76. 31, 31, 3 + ADC_SC1A_PIN_DIFF, 31 + ADC_SC1A_PIN_DIFF, 23, 31, 1, 31 // 62-69 64: A10, 65: A11 (NOT CONNECTED), 66: A21, 68: A25 (no diff)
  77. };
  78. #elif defined(ADC_TEENSY_3_6)
  79. const uint8_t ADC::channel2sc1aADC0[] = {
  80. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  81. 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 3, 31, 31, 31, // 0-13, we treat them as A0-A13
  82. 5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 (A0-A9)
  83. 26, 27, 29, 30, 31, 31, 31, // 24-30: Temp_Sensor, bandgap, VREFH, VREFL.
  84. 31, 31, 17, 18, // 31-34 A12(ADC1), A13(ADC1), A14, A15
  85. 31, 31, 31, 31, 31, 31, 31, 31, 31, // 35-43
  86. 31, 31, 31, 31, 31, 31, 31, 31, 31, // 44-52
  87. 31, 31, 31, 31, 31, 31, 31, 31, 31, // 53-61
  88. 31, 31, 3 + ADC_SC1A_PIN_DIFF, 31 + ADC_SC1A_PIN_DIFF, 23, 31 // 62-67 64: A10, 65: A11 (NOT CONNECTED), 66: A21, 67: A22(ADC1)
  89. };
  90. #elif defined(ADC_TEENSY_4_0)
  91. const uint8_t ADC::channel2sc1aADC0[] = {
  92. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  93. 7, 8, 12, 11, 6, 5, 15, 0, 13, 14, 1, 2, 31, 31, // 0-13, we treat them as A0-A13
  94. 7, 8, 12, 11, 6, 5, 15, 0, 13, 14, // 14-23 (A0-A9)
  95. 1, 2, 31, 31 // A10, A11, A12, A13
  96. };
  97. #elif defined(ADC_TEENSY_4_1)
  98. const uint8_t ADC::channel2sc1aADC0[] = {
  99. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  100. 7, 8, 12, 11, 6, 5, 15, 0, 13, 14, 1, 2, 31, 31, // 0-13, we treat them as A0-A13
  101. 7, 8, 12, 11, 6, 5, 15, 0, 13, 14, // 14-23 (A0-A9)
  102. 1, 2, 31, 31, // A10, A11, A12, A13
  103. 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, //
  104. 31, 31, 9, 10 // A14, A15, A16, A17
  105. };
  106. #endif // defined
  107. ///////// ADC1
  108. #if defined(ADC_TEENSY_3_1)
  109. const uint8_t ADC::channel2sc1aADC1[] = {
  110. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  111. 31, 31, 8, 9, 31, 31, 31, 31, 31, 31, 3, 31, 0, 19, // 0-13, we treat them as A0-A13
  112. 31, 31, 8, 9, 31, 31, 31, 31, 31, 31, // 14-23 (A0-A9)
  113. 31, 31, // 24,25 are digital only pins
  114. 5 + ADC_SC1A_PIN_MUX, 5, 4, 6, 7, 4 + ADC_SC1A_PIN_MUX, 31, 31, // 26-33 26=5a, 27=5b, 28=4b, 29=6b, 30=7b, 31=4a, 32,33 are digital only
  115. 3 + ADC_SC1A_PIN_DIFF, 31 + ADC_SC1A_PIN_DIFF, 0 + ADC_SC1A_PIN_DIFF, 19 + ADC_SC1A_PIN_DIFF, // 34-37 (A10-A13) A11 isn't connected.
  116. 26, 18, 31, 27, 29, 30 // 38-43: temp. sensor, VREF_OUT, A14 (not connected), bandgap, VREFH, VREFL.
  117. };
  118. #elif defined(ADC_TEENSY_3_5)
  119. const uint8_t ADC::channel2sc1aADC1[] = {
  120. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  121. 31, 31, 8, 9, 31, 31, 31, 31, 31, 31, 31, 19, 14, 15, // 0-13, we treat them as A0-A13
  122. 31, 31, 8, 9, 31, 31, 31, 31, 31, 31, // 14-23 (A0-A9)
  123. 26, 27, 29, 30, 18, 31, 31, // 24-30: Temp_Sensor, bandgap, VREFH, VREFL, VREF_OUT
  124. 14, 15, 31, 31, 4, 5, 6, 7, 17, // 31-39 A12-A20
  125. 31, 31, 31, 31, // 40-43
  126. 31, 31, 31, 31, 31, 10, 11, 31, 31, // 44-52, 49: A23, 50: A24
  127. 31, 31, 31, 31, 31, 31, 31, 31, 31, // 53-61
  128. 31, 31, 0 + ADC_SC1A_PIN_DIFF, 19 + ADC_SC1A_PIN_DIFF, 31, 23, 31, 1 // 62-69 64: A10, 65: A11, 67: A22, 69: A26 (not diff)
  129. };
  130. #elif defined(ADC_TEENSY_3_6)
  131. const uint8_t ADC::channel2sc1aADC1[] = {
  132. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  133. 31, 31, 8, 9, 31, 31, 31, 31, 31, 31, 31, 19, 14, 15, // 0-13, we treat them as A0-A13
  134. 31, 31, 8, 9, 31, 31, 31, 31, 31, 31, // 14-23 (A0-A9)
  135. 26, 27, 29, 30, 18, 31, 31, // 24-30: Temp_Sensor, bandgap, VREFH, VREFL, VREF_OUT
  136. 14, 15, 31, 31, 4, 5, 6, 7, 17, // 31-39 A12-A20
  137. 31, 31, 31, 23, // 40-43: A10(ADC0), A11(ADC0), A21, A22
  138. 31, 31, 31, 31, 31, 10, 11, 31, 31, // 44-52, 49: A23, 50: A24
  139. 31, 31, 31, 31, 31, 31, 31, 31, 31, // 53-61
  140. 31, 31, 0 + ADC_SC1A_PIN_DIFF, 19 + ADC_SC1A_PIN_DIFF, 31, 23 // 61-67 64: A10, 65: A11, 66: A21(ADC0), 67: A22
  141. };
  142. #elif defined(ADC_TEENSY_4_0)
  143. const uint8_t ADC::channel2sc1aADC1[] = {
  144. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  145. 7, 8, 12, 11, 6, 5, 15, 0, 13, 14, 31, 31, 3, 4, // 0-13, we treat them as A0-A13
  146. 7, 8, 12, 11, 6, 5, 15, 0, 13, 14, // 14-23 (A0-A9)
  147. 31, 31, 3, 4 // A10, A11, A12, A13
  148. };
  149. #elif defined(ADC_TEENSY_4_1)
  150. const uint8_t ADC::channel2sc1aADC1[] = {
  151. // new version, gives directly the sc1a number. 0x1F=31 deactivates the ADC.
  152. 7, 8, 12, 11, 6, 5, 15, 0, 13, 14, 31, 31, 3, 4, // 0-13, we treat them as A0-A13
  153. 7, 8, 12, 11, 6, 5, 15, 0, 13, 14, // 14-23 (A0-A9)
  154. 31, 31, 3, 4, // A10, A11, A12, A13
  155. 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, //
  156. 1, 2, 9, 10 // A14, A15, A16, A17
  157. };
  158. #endif
  159. #if defined(ADC_TEENSY_3_1) // Teensy 3.1
  160. const ADC_Module::ADC_NLIST ADC::diff_table_ADC0[] = {
  161. {A10, 0 + ADC_SC1A_PIN_PGA}, {A12, 3}};
  162. const ADC_Module::ADC_NLIST ADC::diff_table_ADC1[] = {
  163. {A10, 3}, {A12, 0 + ADC_SC1A_PIN_PGA}};
  164. #elif defined(ADC_TEENSY_3_0) // Teensy 3.0
  165. const ADC_Module::ADC_NLIST ADC::diff_table_ADC0[] = {
  166. {A10, 0}, {A12, 3}};
  167. #elif defined(ADC_TEENSY_LC) // Teensy LC
  168. const ADC_Module::ADC_NLIST ADC::diff_table_ADC0[] = {
  169. {A10, 0}};
  170. #elif defined(ADC_TEENSY_3_5) || defined(ADC_TEENSY_3_6) // Teensy 3.6// Teensy 3.5
  171. const ADC_Module::ADC_NLIST ADC::diff_table_ADC0[] = {
  172. {A10, 3}};
  173. const ADC_Module::ADC_NLIST ADC::diff_table_ADC1[] = {
  174. {A10, 0}};
  175. #elif defined(ADC_TEENSY_4)
  176. #endif
  177. // translate SC1A to pin number
  178. ///////// ADC0
  179. #if defined(ADC_TEENSY_3_0) || defined(ADC_TEENSY_3_1)
  180. const uint8_t ADC::sc1a2channelADC0[] = {
  181. // new version, gives directly the pin number
  182. 34, 0, 0, 36, 23, 14, 20, 21, 16, 17, 0, 0, 19, 18, // 0-13
  183. 15, 22, 23, 0, 0, 35, 0, 37, // 14-21
  184. 39, 40, 0, 0, 38, 41, 42, 43, // VREF_OUT, A14, temp. sensor, bandgap, VREFH, VREFL.
  185. 0 // 31 means disabled, but just in case
  186. };
  187. #elif defined(ADC_TEENSY_LC)
  188. // Teensy LC
  189. const uint8_t ADC::sc1a2channelADC0[] = {
  190. // new version, gives directly the pin number
  191. 24, 0, 0, 0, 25, 14, 20, 21, 16, 17, 0, 23, 19, 18, // 0-13
  192. 15, 22, 23, 0, 0, 0, 0, 0, // 14-21
  193. 26, 0, 0, 0, 38, 41, 0, 42, 43, // A12, temp. sensor, bandgap, VREFH, VREFL.
  194. 0 // 31 means disabled, but just in case
  195. };
  196. #elif defined(ADC_TEENSY_3_5) || defined(ADC_TEENSY_3_6)
  197. const uint8_t ADC::sc1a2channelADC0[] = {
  198. // new version, gives directly the pin number
  199. 0, 68, 0, 64, 23, 14, 20, 21, 16, 17, 0, 0, 19, 18, // 0-13
  200. 15, 22, 0, 33, 34, 0, 0, 0, // 14-21
  201. 0, 66, 0, 0, 70, 0, 0, 0, // 22-29
  202. 0 // 31 means disabled, but just in case
  203. };
  204. #elif defined(ADC_TEENSY_4_0)
  205. const uint8_t ADC::sc1a2channelADC0[] = {
  206. // new version, gives directly the pin number
  207. 21, 24, 25, 0, 0, 19, 18, 14, 15, 0, 0, 17, 16, 22,
  208. 23, 20, 0, 0, 0, 0, 0, 0, //14-21
  209. 0, 0, 0, 0, 0, 0 //22-27
  210. };
  211. #elif defined(ADC_TEENSY_4_1)
  212. const uint8_t ADC::sc1a2channelADC0[] = {
  213. // new version, gives directly the pin number
  214. 21, 24, 25, 0, 0, 19, 18, 14, 15, 0, 0, 17, 16, 22,
  215. 23, 20, 0, 0, 0, 0, 0, 0, //14-21
  216. 0, 0, 0, 0, 0, 0 //22-27
  217. };
  218. #endif // defined
  219. ///////// ADC1
  220. #if defined(ADC_TEENSY_3_1)
  221. const uint8_t ADC::sc1a2channelADC1[] = { // new version, gives directly the pin number
  222. 36, 0, 0, 34, 28, 26, 29, 30, 16, 17, 0, 0, 0, 0, // 0-13. 5a=26, 5b=27, 4b=28, 4a=31
  223. 0, 0, 0, 0, 39, 37, 0, 0, // 14-21
  224. 0, 0, 0, 0, 38, 41, 0, 42, // 22-29. VREF_OUT, A14, temp. sensor, bandgap, VREFH, VREFL.
  225. 43};
  226. #elif defined(ADC_TEENSY_3_5) || defined(ADC_TEENSY_3_6)
  227. const uint8_t ADC::sc1a2channelADC1[] = { // new version, gives directly the pin number
  228. 0, 69, 0, 0, 35, 36, 37, 38, 0, 0, 49, 50, 0, 0, // 0-13.
  229. 31, 32, 0, 39, 71, 65, 0, 0, // 14-21
  230. 0, 67, 0, 0, 0, 0, 0, 0, // 22-29.
  231. 0};
  232. #elif defined(ADC_TEENSY_4_0)
  233. const uint8_t ADC::sc1a2channelADC1[] = {
  234. // new version, gives directly the pin number
  235. 21, 0, 0, 26, 27, 19, 18, 14, 15, 0, 0, 17, 16, 22, // 0-13
  236. 23, 20, 0, 0, 0, 0, 0, 0, //14-21
  237. 0, 0, 0, 0, 0, 0 //22-27
  238. };
  239. #elif defined(ADC_TEENSY_4_1)
  240. const uint8_t ADC::sc1a2channelADC1[] = {
  241. // new version, gives directly the pin number
  242. 21, 0, 0, 26, 27, 19, 18, 14, 15, 0, 0, 17, 16, 22, // 0-13
  243. 23, 20, 0, 0, 0, 0, 0, 0, //14-21
  244. 0, 0, 0, 0, 0, 0 //22-27
  245. };
  246. #endif
  247. // Constructor
  248. ADC::ADC() : // awkward initialization so there are no -Wreorder warnings
  249. #if ADC_DIFF_PAIRS > 0
  250. adc0_obj(0, channel2sc1aADC0, diff_table_ADC0, ADC0_START)
  251. #ifdef ADC_DUAL_ADCS
  252. ,
  253. adc1_obj(1, channel2sc1aADC1, diff_table_ADC1, ADC1_START)
  254. #endif
  255. #else
  256. adc0_obj(0, channel2sc1aADC0, ADC0_START)
  257. #ifdef ADC_DUAL_ADCS
  258. ,
  259. adc1_obj(1, channel2sc1aADC1, ADC1_START)
  260. #endif
  261. #endif
  262. {
  263. //ctor
  264. //digitalWriteFast(LED_BUILTIN, HIGH);
  265. }
  266. /* Returns the analog value of the pin.
  267. * It waits until the value is read and then returns the result.
  268. * If a comparison has been set up and fails, it will return ADC_ERROR_VALUE.
  269. * This function is interrupt safe, so it will restore the adc to the state it was before being called
  270. * If more than one ADC exists, it will select the module with less workload, you can force a selection using
  271. * adc_num. If you select ADC1 in Teensy 3.0 it will return ADC_ERROR_VALUE.
  272. */
  273. int ADC::analogRead(uint8_t pin, int8_t adc_num)
  274. {
  275. #ifdef ADC_SINGLE_ADC
  276. return adc0->analogRead(pin); // use ADC0
  277. #else
  278. /* Teensy 3.1
  279. */
  280. if (adc_num == -1)
  281. { // use no ADC in particular
  282. // check which ADC can read the pin
  283. bool adc0Pin = adc0->checkPin(pin);
  284. bool adc1Pin = adc1->checkPin(pin);
  285. if (adc0Pin && adc1Pin)
  286. { // Both ADCs
  287. if ((adc0->num_measurements) > (adc1->num_measurements))
  288. { // use the ADC with less workload
  289. return adc1->analogRead(pin);
  290. }
  291. else
  292. {
  293. return adc0->analogRead(pin);
  294. }
  295. }
  296. else if (adc0Pin)
  297. { // ADC0
  298. return adc0->analogRead(pin);
  299. }
  300. else if (adc1Pin)
  301. { // ADC1
  302. return adc1->analogRead(pin);
  303. }
  304. else
  305. { // pin not valid in any ADC
  306. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  307. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  308. return ADC_ERROR_VALUE; // all others are invalid
  309. }
  310. }
  311. else if (adc_num == 0)
  312. { // user wants ADC0
  313. return adc0->analogRead(pin);
  314. }
  315. else if (adc_num == 1)
  316. { // user wants ADC 1
  317. return adc1->analogRead(pin);
  318. }
  319. adc0->fail_flag |= ADC_ERROR::OTHER;
  320. return ADC_ERROR_VALUE;
  321. #endif
  322. }
  323. #if ADC_DIFF_PAIRS > 0
  324. /* Reads the differential analog value of two pins (pinP - pinN).
  325. * It waits until the value is read and then returns the result.
  326. * If a comparison has been set up and fails, it will return ADC_ERROR_VALUE.
  327. * \param pinP must be A10 or A12.
  328. * \param pinN must be A11 (if pinP=A10) or A13 (if pinP=A12).
  329. * Other pins will return ADC_ERROR_VALUE.
  330. * This function is interrupt safe, so it will restore the adc to the state it was before being called
  331. * If more than one ADC exists, it will select the module with less workload, you can force a selection using
  332. * adc_num. If you select ADC1 in Teensy 3.0 it will return ADC_ERROR_VALUE.
  333. */
  334. int ADC::analogReadDifferential(uint8_t pinP, uint8_t pinN, int8_t adc_num)
  335. {
  336. #ifdef ADC_SINGLE_ADC
  337. return adc0->analogReadDifferential(pinP, pinN); // use ADC0
  338. #else
  339. /* Teensy 3.1
  340. */
  341. if (adc_num == -1)
  342. { // use no ADC in particular
  343. // check which ADC can read the pin
  344. bool adc0Pin = adc0->checkDifferentialPins(pinP, pinN);
  345. bool adc1Pin = adc1->checkDifferentialPins(pinP, pinN);
  346. if (adc0Pin && adc1Pin)
  347. { // Both ADCs
  348. if ((adc0->num_measurements) > (adc1->num_measurements))
  349. { // use the ADC with less workload
  350. return adc1->analogReadDifferential(pinP, pinN);
  351. }
  352. else
  353. {
  354. return adc0->analogReadDifferential(pinP, pinN);
  355. }
  356. }
  357. else if (adc0Pin)
  358. { // ADC0
  359. return adc0->analogReadDifferential(pinP, pinN);
  360. }
  361. else if (adc1Pin)
  362. { // ADC1
  363. return adc1->analogReadDifferential(pinP, pinN);
  364. }
  365. else
  366. { // pins not valid in any ADC
  367. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  368. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  369. return ADC_ERROR_VALUE; // all others are invalid
  370. }
  371. }
  372. else if (adc_num == 0)
  373. { // user wants ADC0
  374. return adc0->analogReadDifferential(pinP, pinN);
  375. }
  376. else if (adc_num == 1)
  377. { // user wants ADC 1
  378. return adc1->analogReadDifferential(pinP, pinN);
  379. }
  380. adc0->fail_flag |= ADC_ERROR::OTHER;
  381. return ADC_ERROR_VALUE;
  382. #endif
  383. }
  384. #endif
  385. // Starts an analog measurement on the pin and enables interrupts.
  386. /* It returns immediately, get value with readSingle().
  387. * If the pin is incorrect it returns ADC_ERROR_VALUE
  388. * This function is interrupt safe. The ADC interrupt will restore the adc to its previous settings and
  389. * restart the adc if it stopped a measurement. If you modify the adc_isr then this won't happen.
  390. */
  391. bool ADC::startSingleRead(uint8_t pin, int8_t adc_num)
  392. {
  393. #ifdef ADC_SINGLE_ADC
  394. return adc0->startSingleRead(pin); // use ADC0
  395. #else
  396. /* Teensy 3.1
  397. */
  398. if (adc_num == -1)
  399. { // use no ADC in particular
  400. // check which ADC can read the pin
  401. bool adc0Pin = adc0->checkPin(pin);
  402. bool adc1Pin = adc1->checkPin(pin);
  403. if (adc0Pin && adc1Pin)
  404. { // Both ADCs
  405. if ((adc0->num_measurements) > (adc1->num_measurements))
  406. { // use the ADC with less workload
  407. return adc1->startSingleRead(pin);
  408. }
  409. else
  410. {
  411. return adc0->startSingleRead(pin);
  412. }
  413. }
  414. else if (adc0Pin)
  415. { // ADC0
  416. return adc0->startSingleRead(pin);
  417. }
  418. else if (adc1Pin)
  419. { // ADC1
  420. return adc1->startSingleRead(pin);
  421. }
  422. else
  423. { // pin not valid in any ADC
  424. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  425. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  426. return false; // all others are invalid
  427. }
  428. }
  429. else if (adc_num == 0)
  430. { // user wants ADC0
  431. return adc0->startSingleRead(pin);
  432. }
  433. else if (adc_num == 1)
  434. { // user wants ADC 1
  435. return adc1->startSingleRead(pin);
  436. }
  437. adc0->fail_flag |= ADC_ERROR::OTHER;
  438. return false;
  439. #endif
  440. }
  441. #if ADC_DIFF_PAIRS > 0
  442. // Start a differential conversion between two pins (pinP - pinN) and enables interrupts.
  443. /* It returns inmediately, get value with readSingle().
  444. * \param pinP must be A10 or A12.
  445. * \param pinN must be A11 (if pinP=A10) or A13 (if pinP=A12).
  446. * Other pins will return ADC_ERROR_DIFF_VALUE.
  447. * This function is interrupt safe. The ADC interrupt will restore the adc to its previous settings and
  448. * restart the adc if it stopped a measurement. If you modify the adc_isr then this won't happen.
  449. */
  450. bool ADC::startSingleDifferential(uint8_t pinP, uint8_t pinN, int8_t adc_num)
  451. {
  452. #ifdef ADC_SINGLE_ADC
  453. return adc0->startSingleDifferential(pinP, pinN); // use ADC0
  454. #else
  455. /* Teensy 3.1
  456. */
  457. if (adc_num == -1)
  458. { // use no ADC in particular
  459. // check which ADC can read the pin
  460. bool adc0Pin = adc0->checkDifferentialPins(pinP, pinN);
  461. bool adc1Pin = adc1->checkDifferentialPins(pinP, pinN);
  462. if (adc0Pin && adc1Pin)
  463. { // Both ADCs
  464. if ((adc0->num_measurements) > (adc1->num_measurements))
  465. { // use the ADC with less workload
  466. return adc1->startSingleDifferential(pinP, pinN);
  467. }
  468. else
  469. {
  470. return adc0->startSingleDifferential(pinP, pinN);
  471. }
  472. }
  473. else if (adc0Pin)
  474. { // ADC0
  475. return adc0->startSingleDifferential(pinP, pinN);
  476. }
  477. else if (adc1Pin)
  478. { // ADC1
  479. return adc1->startSingleDifferential(pinP, pinN);
  480. }
  481. else
  482. { // pins not valid in any ADC
  483. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  484. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  485. return false; // all others are invalid
  486. }
  487. }
  488. else if (adc_num == 0)
  489. { // user wants ADC0
  490. return adc0->startSingleDifferential(pinP, pinN);
  491. }
  492. else if (adc_num == 1)
  493. { // user wants ADC 1
  494. return adc1->startSingleDifferential(pinP, pinN);
  495. }
  496. adc0->fail_flag |= ADC_ERROR::OTHER;
  497. return false;
  498. #endif
  499. }
  500. #endif
  501. // Reads the analog value of a single conversion.
  502. /* Set the conversion with with startSingleRead(pin) or startSingleDifferential(pinP, pinN).
  503. * \return the converted value.
  504. */
  505. int ADC::readSingle(int8_t adc_num)
  506. {
  507. #ifdef ADC_SINGLE_ADC
  508. return adc0->readSingle();
  509. #else
  510. if (adc_num == 1)
  511. { // user wants ADC 1, do nothing if it's a Teensy 3.0
  512. return adc1->readSingle();
  513. }
  514. return adc0->readSingle();
  515. #endif
  516. }
  517. // Starts continuous conversion on the pin.
  518. /* It returns as soon as the ADC is set, use analogReadContinuous() to read the value.
  519. */
  520. bool ADC::startContinuous(uint8_t pin, int8_t adc_num)
  521. {
  522. #ifdef ADC_SINGLE_ADC
  523. return adc0->startContinuous(pin); // use ADC0
  524. #else
  525. /* Teensy 3.1
  526. */
  527. if (adc_num == -1)
  528. { // use no ADC in particular
  529. // check which ADC can read the pin
  530. bool adc0Pin = adc0->checkPin(pin);
  531. bool adc1Pin = adc1->checkPin(pin);
  532. if (adc0Pin && adc1Pin)
  533. { // Both ADCs
  534. if ((adc0->num_measurements) > (adc1->num_measurements))
  535. { // use the ADC with less workload
  536. return adc1->startContinuous(pin);
  537. }
  538. else
  539. {
  540. return adc0->startContinuous(pin);
  541. }
  542. }
  543. else if (adc0Pin)
  544. { // ADC0
  545. return adc0->startContinuous(pin);
  546. }
  547. else if (adc1Pin)
  548. { // ADC1
  549. return adc1->startContinuous(pin);
  550. }
  551. else
  552. { // pin not valid in any ADC
  553. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  554. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  555. return false; // all others are invalid
  556. }
  557. }
  558. else if (adc_num == 0)
  559. { // user wants ADC0
  560. return adc0->startContinuous(pin);
  561. }
  562. else if (adc_num == 1)
  563. { // user wants ADC 1
  564. return adc1->startContinuous(pin);
  565. }
  566. adc0->fail_flag |= ADC_ERROR::OTHER;
  567. return false;
  568. #endif
  569. }
  570. #if ADC_DIFF_PAIRS > 0
  571. // Starts continuous conversion between the pins (pinP-pinN).
  572. /* It returns as soon as the ADC is set, use analogReadContinuous() to read the value.
  573. * \param pinP must be A10 or A12.
  574. * \param pinN must be A11 (if pinP=A10) or A13 (if pinP=A12).
  575. * Other pins will return ADC_ERROR_DIFF_VALUE.
  576. */
  577. bool ADC::startContinuousDifferential(uint8_t pinP, uint8_t pinN, int8_t adc_num)
  578. {
  579. #ifdef ADC_SINGLE_ADC
  580. return adc0->startContinuousDifferential(pinP, pinN); // use ADC0
  581. #else
  582. /* Teensy 3.1
  583. */
  584. if (adc_num == -1)
  585. { // use no ADC in particular
  586. // check which ADC can read the pin
  587. bool adc0Pin = adc0->checkDifferentialPins(pinP, pinN);
  588. bool adc1Pin = adc1->checkDifferentialPins(pinP, pinN);
  589. if (adc0Pin && adc1Pin)
  590. { // Both ADCs
  591. if ((adc0->num_measurements) > (adc1->num_measurements))
  592. { // use the ADC with less workload
  593. return adc1->startContinuousDifferential(pinP, pinN);
  594. }
  595. else
  596. {
  597. return adc0->startContinuousDifferential(pinP, pinN);
  598. }
  599. }
  600. else if (adc0Pin)
  601. { // ADC0
  602. return adc0->startContinuousDifferential(pinP, pinN);
  603. }
  604. else if (adc1Pin)
  605. { // ADC1
  606. return adc1->startContinuousDifferential(pinP, pinN);
  607. }
  608. else
  609. { // pins not valid in any ADC
  610. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  611. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  612. return false; // all others are invalid
  613. }
  614. }
  615. else if (adc_num == 0)
  616. { // user wants ADC0
  617. return adc0->startContinuousDifferential(pinP, pinN);
  618. }
  619. else if (adc_num == 1)
  620. { // user wants ADC 1
  621. return adc1->startContinuousDifferential(pinP, pinN);
  622. }
  623. adc0->fail_flag |= ADC_ERROR::OTHER;
  624. return false;
  625. #endif
  626. }
  627. #endif
  628. //! Reads the analog value of a continuous conversion.
  629. /** Set the continuous conversion with with analogStartContinuous(pin) or startContinuousDifferential(pinP, pinN).
  630. * \return the last converted value.
  631. * If single-ended and 16 bits it's necessary to typecast it to an unsigned type (like uint16_t),
  632. * otherwise values larger than 3.3/2 V are interpreted as negative!
  633. */
  634. int ADC::analogReadContinuous(int8_t adc_num)
  635. {
  636. #ifdef ADC_SINGLE_ADC
  637. return adc0->analogReadContinuous();
  638. #else
  639. if (adc_num == 1)
  640. { // user wants ADC 1, do nothing if it's a Teensy 3.0
  641. return adc1->analogReadContinuous();
  642. }
  643. return adc0->analogReadContinuous();
  644. #endif
  645. }
  646. //! Stops continuous conversion
  647. void ADC::stopContinuous(int8_t adc_num)
  648. {
  649. #ifdef ADC_SINGLE_ADC
  650. adc0->stopContinuous();
  651. #else
  652. if (adc_num == 1)
  653. { // user wants ADC 1, do nothing if it's a Teensy 3.0
  654. adc1->stopContinuous();
  655. return;
  656. }
  657. adc0->stopContinuous();
  658. return;
  659. #endif
  660. }
  661. //////////////// SYNCHRONIZED BLOCKING METHODS //////////////////
  662. ///// ONLY FOR BOARDS WITH MORE THAN ONE ADC /////
  663. /////////////////////////////////////////////////////////////////
  664. #ifdef ADC_DUAL_ADCS
  665. /*Returns the analog values of both pins, measured at the same time by the two ADC modules.
  666. * It waits until the value is read and then returns the result as a struct Sync_result,
  667. * use Sync_result.result_adc0 and Sync_result.result_adc1.
  668. * If a comparison has been set up and fails, it will return ADC_ERROR_VALUE in both fields of the struct.
  669. */
  670. ADC::Sync_result ADC::analogSynchronizedRead(uint8_t pin0, uint8_t pin1)
  671. {
  672. Sync_result res = {ADC_ERROR_VALUE, ADC_ERROR_VALUE};
  673. // check pins
  674. if (!adc0->checkPin(pin0))
  675. {
  676. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  677. return res;
  678. }
  679. if (!adc1->checkPin(pin1))
  680. {
  681. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  682. return res;
  683. }
  684. // check if we are interrupting a measurement, store setting if so.
  685. // vars to save the current state of the ADC in case it's in use
  686. ADC_Module::ADC_Config old_adc0_config = {};
  687. uint8_t wasADC0InUse = adc0->isConverting(); // is the ADC running now?
  688. if (wasADC0InUse)
  689. { // this means we're interrupting a conversion
  690. // save the current conversion config, the adc isr will restore the adc
  691. __disable_irq();
  692. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  693. adc0->saveConfig(&old_adc0_config);
  694. __enable_irq();
  695. }
  696. ADC_Module::ADC_Config old_adc1_config = {};
  697. uint8_t wasADC1InUse = adc1->isConverting(); // is the ADC running now?
  698. if (wasADC1InUse)
  699. { // this means we're interrupting a conversion
  700. // save the current conversion config, the adc isr will restore the adc
  701. __disable_irq();
  702. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  703. adc1->saveConfig(&old_adc1_config);
  704. __enable_irq();
  705. }
  706. // no continuous mode
  707. adc0->singleMode();
  708. adc1->singleMode();
  709. // start both measurements
  710. adc0->startReadFast(pin0);
  711. adc1->startReadFast(pin1);
  712. // wait for both ADCs to finish
  713. while ((adc0->isConverting()) || (adc1->isConverting()))
  714. { // wait for both to finish
  715. yield();
  716. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  717. }
  718. __disable_irq(); // make sure nothing interrupts this part
  719. if (adc0->isComplete())
  720. { // conversion succeded
  721. res.result_adc0 = adc0->readSingle();
  722. }
  723. else
  724. { // comparison was false
  725. adc0->fail_flag |= ADC_ERROR::COMPARISON;
  726. }
  727. if (adc1->isComplete())
  728. { // conversion succeded
  729. res.result_adc1 = adc1->readSingle();
  730. }
  731. else
  732. { // comparison was false
  733. adc1->fail_flag |= ADC_ERROR::COMPARISON;
  734. }
  735. __enable_irq();
  736. // if we interrupted a conversion, set it again
  737. if (wasADC0InUse)
  738. {
  739. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  740. adc0->loadConfig(&old_adc0_config);
  741. }
  742. if (wasADC1InUse)
  743. {
  744. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  745. adc1->loadConfig(&old_adc1_config);
  746. }
  747. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  748. return res;
  749. }
  750. #if ADC_DIFF_PAIRS > 0
  751. /*Returns the diff analog values of both sets of pins, measured at the same time by the two ADC modules.
  752. * It waits until the value is read and then returns the result as a struct Sync_result,
  753. * use Sync_result.result_adc0 and Sync_result.result_adc1.
  754. * If a comparison has been set up and fails, it will return ADC_ERROR_VALUE in both fields of the struct.
  755. */
  756. ADC::Sync_result ADC::analogSynchronizedReadDifferential(uint8_t pin0P, uint8_t pin0N, uint8_t pin1P, uint8_t pin1N)
  757. {
  758. Sync_result res = {ADC_ERROR_VALUE, ADC_ERROR_VALUE};
  759. ;
  760. // check pins
  761. if (!adc0->checkDifferentialPins(pin0P, pin0N))
  762. {
  763. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  764. return res; // all others are invalid
  765. }
  766. if (!adc1->checkDifferentialPins(pin1P, pin1N))
  767. {
  768. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  769. return res; // all others are invalid
  770. }
  771. uint8_t resolution0 = adc0->getResolution();
  772. uint8_t resolution1 = adc1->getResolution();
  773. // check if we are interrupting a measurement, store setting if so.
  774. // vars to save the current state of the ADC in case it's in use
  775. ADC_Module::ADC_Config old_adc0_config = {};
  776. uint8_t wasADC0InUse = adc0->isConverting(); // is the ADC running now?
  777. if (wasADC0InUse)
  778. { // this means we're interrupting a conversion
  779. // save the current conversion config, the adc isr will restore the adc
  780. __disable_irq();
  781. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  782. adc0->saveConfig(&old_adc0_config);
  783. __enable_irq();
  784. }
  785. ADC_Module::ADC_Config old_adc1_config = {};
  786. uint8_t wasADC1InUse = adc1->isConverting(); // is the ADC running now?
  787. if (wasADC1InUse)
  788. { // this means we're interrupting a conversion
  789. // save the current conversion config, the adc isr will restore the adc
  790. __disable_irq();
  791. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  792. adc1->saveConfig(&old_adc1_config);
  793. __enable_irq();
  794. }
  795. // no continuous mode
  796. adc0->singleMode();
  797. adc1->singleMode();
  798. // start both measurements
  799. adc0->startDifferentialFast(pin0P, pin0N);
  800. adc1->startDifferentialFast(pin1P, pin1N);
  801. // wait for both ADCs to finish
  802. while ((adc0->isConverting()) || (adc1->isConverting()))
  803. {
  804. yield();
  805. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  806. }
  807. __disable_irq(); // make sure nothing interrupts this part
  808. if (adc0->isComplete())
  809. { // conversion succeded
  810. res.result_adc0 = adc0->readSingle();
  811. if (resolution0 == 16)
  812. { // 16 bit differential is actually 15 bit + 1 bit sign
  813. res.result_adc0 *= 2; // multiply by 2 as if it were really 16 bits, so that getMaxValue gives a correct value.
  814. }
  815. }
  816. else
  817. { // comparison was false
  818. adc0->fail_flag |= ADC_ERROR::COMPARISON;
  819. }
  820. if (adc1->isComplete())
  821. { // conversion succeded
  822. res.result_adc1 = adc1->readSingle();
  823. if (resolution1 == 16)
  824. { // 16 bit differential is actually 15 bit + 1 bit sign
  825. res.result_adc1 *= 2; // multiply by 2 as if it were really 16 bits, so that getMaxValue gives a correct value.
  826. }
  827. }
  828. else
  829. { // comparison was false
  830. adc1->fail_flag |= ADC_ERROR::COMPARISON;
  831. }
  832. __enable_irq();
  833. // if we interrupted a conversion, set it again
  834. if (wasADC0InUse)
  835. {
  836. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  837. adc0->loadConfig(&old_adc0_config);
  838. }
  839. if (wasADC1InUse)
  840. {
  841. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  842. adc1->loadConfig(&old_adc1_config);
  843. }
  844. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  845. return res;
  846. }
  847. #endif
  848. /////////////// SYNCHRONIZED NON-BLOCKING METHODS //////////////
  849. // Starts an analog measurement at the same time on the two ADC modules
  850. /* It returns inmediately, get value with readSynchronizedSingle().
  851. * If the pin is incorrect it returns false
  852. * If this function interrupts a measurement, it stores the settings in adc_config
  853. */
  854. bool ADC::startSynchronizedSingleRead(uint8_t pin0, uint8_t pin1)
  855. {
  856. // check pins
  857. if (!adc0->checkPin(pin0))
  858. {
  859. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  860. return false;
  861. }
  862. if (!adc1->checkPin(pin1))
  863. {
  864. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  865. return false;
  866. }
  867. // check if we are interrupting a measurement, store setting if so.
  868. adc0->adcWasInUse = adc0->isConverting(); // is the ADC running now?
  869. if (adc0->adcWasInUse)
  870. { // this means we're interrupting a conversion
  871. // save the current conversion config, the adc isr will restore the adc
  872. __disable_irq();
  873. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  874. adc0->saveConfig(&adc0->adc_config);
  875. __enable_irq();
  876. }
  877. adc1->adcWasInUse = adc1->isConverting(); // is the ADC running now?
  878. if (adc1->adcWasInUse)
  879. { // this means we're interrupting a conversion
  880. // save the current conversion config, the adc isr will restore the adc
  881. __disable_irq();
  882. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  883. adc1->saveConfig(&adc1->adc_config);
  884. __enable_irq();
  885. }
  886. // no continuous mode
  887. adc0->singleMode();
  888. adc1->singleMode();
  889. // start both measurements
  890. adc0->startReadFast(pin0);
  891. adc1->startReadFast(pin1);
  892. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  893. return true;
  894. }
  895. #if ADC_DIFF_PAIRS > 0
  896. // Start a differential conversion between two pins (pin0P - pin0N) and (pin1P - pin1N)
  897. /* It returns inmediately, get value with readSynchronizedSingle().
  898. * \param pinP must be A10 or A12.
  899. * \param pinN must be A11 (if pinP=A10) or A13 (if pinP=A12).
  900. * Other pins will return false.
  901. * If this function interrupts a measurement, it stores the settings in adc_config
  902. */
  903. bool ADC::startSynchronizedSingleDifferential(uint8_t pin0P, uint8_t pin0N, uint8_t pin1P, uint8_t pin1N)
  904. {
  905. // check pins
  906. if (!adc0->checkDifferentialPins(pin0P, pin0N))
  907. {
  908. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  909. return false; // all others are invalid
  910. }
  911. if (!adc1->checkDifferentialPins(pin1P, pin1N))
  912. {
  913. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  914. return false; // all others are invalid
  915. }
  916. // check if we are interrupting a measurement, store setting if so.
  917. adc0->adcWasInUse = adc0->isConverting(); // is the ADC running now?
  918. if (adc0->adcWasInUse)
  919. { // this means we're interrupting a conversion
  920. // save the current conversion config, the adc isr will restore the adc
  921. __disable_irq();
  922. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  923. adc0->saveConfig(&adc0->adc_config);
  924. __enable_irq();
  925. }
  926. adc1->adcWasInUse = adc1->isConverting(); // is the ADC running now?
  927. if (adc1->adcWasInUse)
  928. { // this means we're interrupting a conversion
  929. // save the current conversion config, the adc isr will restore the adc
  930. __disable_irq();
  931. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  932. adc1->saveConfig(&adc1->adc_config);
  933. __enable_irq();
  934. }
  935. // no continuous mode
  936. adc0->singleMode();
  937. adc1->singleMode();
  938. // start both measurements
  939. adc0->startDifferentialFast(pin0P, pin0N);
  940. adc1->startDifferentialFast(pin1P, pin1N);
  941. //digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  942. return true;
  943. }
  944. #endif
  945. // Reads the analog value of a single conversion.
  946. /*
  947. * \return the converted value.
  948. */
  949. ADC::Sync_result ADC::readSynchronizedSingle()
  950. {
  951. ADC::Sync_result res;
  952. res.result_adc0 = adc0->readSingle();
  953. res.result_adc1 = adc1->readSingle();
  954. return res;
  955. }
  956. ///////////// SYNCHRONIZED CONTINUOUS CONVERSION METHODS ////////////
  957. //! Starts a continuous conversion in both ADCs simultaneously
  958. /** Use readSynchronizedContinuous to get the values
  959. *
  960. */
  961. bool ADC::startSynchronizedContinuous(uint8_t pin0, uint8_t pin1)
  962. {
  963. // check pins
  964. if (!adc0->checkPin(pin0))
  965. {
  966. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  967. return false;
  968. }
  969. if (!adc1->checkPin(pin1))
  970. {
  971. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  972. return false;
  973. }
  974. adc0->continuousMode();
  975. adc1->continuousMode();
  976. __disable_irq(); // both measurements should have a maximum delay of an instruction time
  977. adc0->startReadFast(pin0);
  978. adc1->startReadFast(pin1);
  979. __enable_irq();
  980. return true;
  981. }
  982. #if ADC_DIFF_PAIRS > 0
  983. //! Starts a continuous differential conversion in both ADCs simultaneously
  984. /** Use readSynchronizedContinuous to get the values
  985. *
  986. */
  987. bool ADC::startSynchronizedContinuousDifferential(uint8_t pin0P, uint8_t pin0N, uint8_t pin1P, uint8_t pin1N)
  988. {
  989. // check pins
  990. if (!adc0->checkDifferentialPins(pin0P, pin0N))
  991. {
  992. adc0->fail_flag |= ADC_ERROR::WRONG_PIN;
  993. return false; // all others are invalid
  994. }
  995. if (!adc1->checkDifferentialPins(pin1P, pin1N))
  996. {
  997. adc1->fail_flag |= ADC_ERROR::WRONG_PIN;
  998. return false; // all others are invalid
  999. }
  1000. adc0->continuousMode();
  1001. adc1->continuousMode();
  1002. __disable_irq();
  1003. adc0->startDifferentialFast(pin0P, pin0N);
  1004. adc1->startDifferentialFast(pin1P, pin1N);
  1005. __enable_irq();
  1006. return true;
  1007. }
  1008. #endif
  1009. //! Returns the values of both ADCs.
  1010. ADC::Sync_result ADC::readSynchronizedContinuous()
  1011. {
  1012. ADC::Sync_result res;
  1013. res.result_adc0 = adc0->analogReadContinuous();
  1014. res.result_adc1 = adc1->analogReadContinuous();
  1015. return res;
  1016. }
  1017. //! Stops synchronous continuous conversion
  1018. void ADC::stopSynchronizedContinuous()
  1019. {
  1020. adc0->stopContinuous();
  1021. adc1->stopContinuous();
  1022. }
  1023. #endif