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.

578 lines
25KB

  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. /* TODO
  26. * - Function to measure more that 1 pin consecutively (stream?)
  27. *
  28. * bugs:
  29. * - comparison values in 16 bit differential mode are twice what they should be
  30. */
  31. /*! \mainpage ADC
  32. Teensy 4.x, 3.x, LC ADC library
  33. This manual is divided in the following sections:
  34. - \subpage adc_doc "ADC"
  35. - \subpage adc_module "ADC Module"
  36. - \subpage settings "Board settings"
  37. - \subpage error "ADC error codes"
  38. - \subpage util "ADC util"
  39. */
  40. /*! \page adc_doc ADC
  41. Make Analog to Digital conversions using the ADC interface.
  42. See the ADC class for all methods.
  43. */
  44. #ifndef ADC_H
  45. #define ADC_H
  46. #define ADC_0 0
  47. #define ADC_1 1
  48. //enum class ADC_NUM {ADC_0, ADC_1}; // too verbose, but it'd avoid some mistakes
  49. // include ADC module class
  50. #include "ADC_Module.h"
  51. #ifdef __cplusplus
  52. extern "C"
  53. {
  54. #endif
  55. /** Class ADC: Controls the Teensy 3.x, 4 ADC
  56. *
  57. */
  58. class ADC
  59. {
  60. protected:
  61. private:
  62. // ADCs objects
  63. ADC_Module adc0_obj;
  64. #ifdef ADC_DUAL_ADCS
  65. ADC_Module adc1_obj;
  66. #endif
  67. //! Number of ADC objects
  68. const uint8_t num_ADCs = ADC_NUM_ADCS;
  69. public:
  70. /** Default constructor */
  71. ADC();
  72. // create both adc objects
  73. //! Object to control the ADC0
  74. ADC_Module *const adc0 = &adc0_obj; // adc object pointer
  75. #ifdef ADC_DUAL_ADCS
  76. //! Object to control the ADC1
  77. ADC_Module *const adc1 = &adc1_obj; // adc object pointer
  78. #endif
  79. #ifdef ADC_SINGLE_ADC
  80. //! Array with the ADC Modules
  81. ADC_Module *const adc[ADC_NUM_ADCS] = {adc0};
  82. #else
  83. //! Array with the ADC Modules
  84. ADC_Module *const adc[ADC_NUM_ADCS] = {adc0, adc1};
  85. #endif
  86. /////////////// METHODS TO SET/GET SETTINGS OF THE ADC ////////////////////
  87. //! Set the voltage reference you prefer, default is vcc
  88. /*! It recalibrates at the end.
  89. * \param type can be ADC_REFERENCE::REF_3V3, ADC_REFERENCE::REF_1V2 (not for Teensy LC) or ADC_REFERENCE::REF_EXT
  90. * \param adc_num ADC number to change.
  91. */
  92. __attribute__((error("Use adc->adcX->setReference instead"))) void setReference(ADC_REFERENCE type, int8_t adc_num = -1);
  93. //! Change the resolution of the measurement.
  94. /*!
  95. * \param bits is the number of bits of resolution.
  96. * For single-ended measurements: 8, 10, 12 or 16 bits.
  97. * For differential measurements: 9, 11, 13 or 16 bits.
  98. * If you want something in between (11 bits single-ended for example) select the immediate higher
  99. * and shift the result one to the right.
  100. * Whenever you change the resolution, change also the comparison values (if you use them).
  101. * \param adc_num ADC number to change.
  102. */
  103. __attribute__((error("Use adc->adcX->setResolution instead"))) void setResolution(uint8_t bits, int8_t adc_num = -1);
  104. //! Returns the resolution of the ADC_Module.
  105. /**
  106. * \param adc_num ADC number to query.
  107. * \return the resolution of adc_num ADC.
  108. */
  109. __attribute__((error("Use adc->adcX->getResolution instead")))
  110. uint8_t
  111. getResolution(int8_t adc_num = -1);
  112. //! Returns the maximum value for a measurement: 2^res-1.
  113. /**
  114. * \param adc_num ADC number to query.
  115. * \return the maximum value of adc_num ADC.
  116. */
  117. __attribute__((error("Use adc->adcX->getMaxValue instead")))
  118. uint32_t
  119. getMaxValue(int8_t adc_num = -1);
  120. //! Sets the conversion speed (changes the ADC clock, ADCK)
  121. /**
  122. * \param speed can be any from the ADC_CONVERSION_SPEED enum: VERY_LOW_SPEED, LOW_SPEED, MED_SPEED, HIGH_SPEED_16BITS, HIGH_SPEED, VERY_HIGH_SPEED,
  123. * ADACK_2_4, ADACK_4_0, ADACK_5_2 or ADACK_6_2.
  124. *
  125. * VERY_LOW_SPEED is guaranteed to be the lowest possible speed within specs for resolutions less than 16 bits (higher than 1 MHz),
  126. * it's different from LOW_SPEED only for 24, 4 or 2 MHz bus frequency.
  127. * LOW_SPEED is guaranteed to be the lowest possible speed within specs for all resolutions (higher than 2 MHz).
  128. * MED_SPEED is always >= LOW_SPEED and <= HIGH_SPEED.
  129. * HIGH_SPEED_16BITS is guaranteed to be the highest possible speed within specs for all resolutions (lower or eq than 12 MHz).
  130. * HIGH_SPEED is guaranteed to be the highest possible speed within specs for resolutions less than 16 bits (lower or eq than 18 MHz).
  131. * VERY_HIGH_SPEED may be out of specs, it's different from HIGH_SPEED only for 48, 40 or 24 MHz bus frequency.
  132. *
  133. * Additionally the conversion speed can also be ADACK_2_4, ADACK_4_0, ADACK_5_2 and ADACK_6_2,
  134. * where the numbers are the frequency of the ADC clock (ADCK) in MHz and are independent on the bus speed.
  135. * This is useful if you are using the Teensy at a very low clock frequency but want faster conversions,
  136. * but if F_BUS<F_ADCK, you can't use VERY_HIGH_SPEED for sampling speed.
  137. * \param adc_num ADC number to change.
  138. */
  139. __attribute__((error("Use adc->adcX->setConversionSpeed instead"))) void setConversionSpeed(ADC_CONVERSION_SPEED speed, int8_t adc_num = -1);
  140. //! Sets the sampling speed
  141. /** Increase the sampling speed for low impedance sources, decrease it for higher impedance ones.
  142. * \param speed can be any of the ADC_SAMPLING_SPEED enum: VERY_LOW_SPEED, LOW_SPEED, MED_SPEED, HIGH_SPEED or VERY_HIGH_SPEED.
  143. *
  144. * VERY_LOW_SPEED is the lowest possible sampling speed (+24 ADCK).
  145. * LOW_SPEED adds +16 ADCK.
  146. * MED_SPEED adds +10 ADCK.
  147. * HIGH_SPEED adds +6 ADCK.
  148. * VERY_HIGH_SPEED is the highest possible sampling speed (0 ADCK added).
  149. * \param adc_num ADC number to change.
  150. */
  151. __attribute__((error("Use adc->adcX->setSamplingSpeed instead"))) void setSamplingSpeed(ADC_SAMPLING_SPEED speed, int8_t adc_num = -1);
  152. //! Set the number of averages
  153. /*!
  154. * \param num can be 0, 4, 8, 16 or 32.
  155. * \param adc_num ADC number to change.
  156. */
  157. __attribute__((error("Use adc->adcX->setAveraging instead"))) void setAveraging(uint8_t num, int8_t adc_num = -1);
  158. //! Enable interrupts
  159. /** An IRQ_ADCx Interrupt will be raised when the conversion is completed
  160. * (including hardware averages and if the comparison (if any) is true).
  161. * \param adc_num ADC number to change.
  162. * \param isr function (returns void and accepts no arguments) that will be executed after an interrupt.
  163. * \param priority Interrupt priority, highest is 0, lowest is 255.
  164. */
  165. __attribute__((error("Use adc->adcX->enableInterrupts instead"))) void enableInterrupts(void (*isr)(void), uint8_t priority = 255, int8_t adc_num = -1);
  166. //! Disable interrupts
  167. /**
  168. * \param adc_num ADC number to change.
  169. */
  170. __attribute__((error("Use adc->adcX->disableInterrupts instead"))) void disableInterrupts(int8_t adc_num = -1);
  171. #ifdef ADC_USE_DMA
  172. //! Enable DMA request
  173. /** An ADC DMA request will be raised when the conversion is completed
  174. * (including hardware averages and if the comparison (if any) is true).
  175. * \param adc_num ADC number to change.
  176. */
  177. __attribute__((error("Use adc->adcX->enableDMA instead"))) void enableDMA(int8_t adc_num = -1);
  178. //! Disable ADC DMA request
  179. /**
  180. * \param adc_num ADC number to change.
  181. */
  182. __attribute__((error("Use adc->adcX->disableDMA instead"))) void disableDMA(int8_t adc_num = -1);
  183. #endif
  184. //! Enable the compare function to a single value
  185. /** A conversion will be completed only when the ADC value
  186. * is >= compValue (greaterThan=1) or < compValue (greaterThan=0)
  187. * Call it after changing the resolution
  188. * Use with interrupts or poll conversion completion with isComplete()
  189. * \param compValue value to compare
  190. * \param greaterThan true or false
  191. * \param adc_num ADC number to change.
  192. */
  193. __attribute__((error("Use adc->adcX->enableCompare instead"))) void enableCompare(int16_t compValue, bool greaterThan, int8_t adc_num = -1);
  194. //! Enable the compare function to a range
  195. /** A conversion will be completed only when the ADC value is inside (insideRange=1) or outside (=0)
  196. * the range given by (lowerLimit, upperLimit),including (inclusive=1) the limits or not (inclusive=0).
  197. * See Table 31-78, p. 617 of the freescale manual.
  198. * Call it after changing the resolution
  199. * Use with interrupts or poll conversion completion with isComplete()
  200. * \param lowerLimit lower value to compare
  201. * \param upperLimit upper value to compare
  202. * \param insideRange true or false
  203. * \param inclusive true or false
  204. * \param adc_num ADC number to change.
  205. */
  206. __attribute__((error("Use adc->adcX->enableCompareRange instead"))) void enableCompareRange(int16_t lowerLimit, int16_t upperLimit, bool insideRange, bool inclusive, int8_t adc_num = -1);
  207. //! Disable the compare function
  208. /**
  209. * \param adc_num ADC number to change.
  210. */
  211. __attribute__((error("Use adc->adcX->disableCompare instead"))) void disableCompare(int8_t adc_num = -1);
  212. #ifdef ADC_USE_PGA
  213. //! Enable and set PGA
  214. /** Enables the PGA and sets the gain
  215. * Use only for signals lower than 1.2 V and only in differential mode
  216. * \param gain can be 1, 2, 4, 8, 16, 32 or 64
  217. * \param adc_num ADC number to change.
  218. */
  219. __attribute__((error("Use adc->adcX->enablePGA instead"))) void enablePGA(uint8_t gain, int8_t adc_num = -1);
  220. //! Returns the PGA level
  221. /** PGA level = from 1 to 64
  222. * \param adc_num ADC number to query.
  223. * \return PGA level = from 1 to 64
  224. */
  225. __attribute__((error("Use adc->adcX->getPGA instead")))
  226. uint8_t
  227. getPGA(int8_t adc_num = -1);
  228. //! Disable PGA
  229. /**
  230. * \param adc_num ADC number to query
  231. */
  232. __attribute__((error("Use adc->adcX->disablePGA instead"))) void disablePGA(int8_t adc_num = -1);
  233. #endif
  234. ////////////// INFORMATION ABOUT THE STATE OF THE ADC /////////////////
  235. //! Is the ADC converting at the moment?
  236. /**
  237. * \param adc_num ADC number to query
  238. * \return true if yes, false if not.
  239. */
  240. __attribute__((error("Use adc->adcX->isConverting instead"))) bool isConverting(int8_t adc_num = -1);
  241. //! Is an ADC conversion ready?
  242. /** When a value is read this function returns 0 until a new value exists
  243. * So it only makes sense to call it with continuous or non-blocking methods
  244. * \param adc_num ADC number to query
  245. * \return true if yes, false if not.
  246. */
  247. __attribute__((error("Use adc->adcX->isComplete instead"))) bool isComplete(int8_t adc_num = -1);
  248. #if ADC_DIFF_PAIRS > 0
  249. //! Is the ADC in differential mode?
  250. /**
  251. * \param adc_num ADC number to query
  252. * \return true or false
  253. */
  254. __attribute__((error("Use adc->adcX->isDifferential instead"))) bool isDifferential(int8_t adc_num = -1);
  255. #endif
  256. //! Is the ADC in continuous mode?
  257. /**
  258. * \param adc_num ADC number to query
  259. * \return true or false
  260. */
  261. __attribute__((error("Use adc->adcX->isContinuous instead"))) bool isContinuous(int8_t adc_num = -1);
  262. //////////////// BLOCKING CONVERSION METHODS //////////////////
  263. //! Returns the analog value of the pin.
  264. /** It waits until the value is read and then returns the result.
  265. * If a comparison has been set up and fails, it will return ADC_ERROR_VALUE.
  266. * This function is interrupt safe, so it will restore the adc to the state it was before being called
  267. * If more than one ADC exists, it will select the module with less workload, you can force a selection using
  268. * adc_num. If you select ADC1 in Teensy 3.0 it will return ADC_ERROR_VALUE.
  269. * \param pin can be any of the analog pins
  270. * \param adc_num ADC_X ADC module
  271. * \return the value of the pin.
  272. */
  273. int analogRead(uint8_t pin, int8_t adc_num = -1);
  274. //! Returns the analog value of the special internal source, such as the temperature sensor.
  275. /** It calls analogRead(uint8_t pin) internally, with the correct value for the pin for all boards.
  276. * Possible values:
  277. * TEMP_SENSOR, Temperature sensor.
  278. * VREF_OUT, 1.2 V reference (switch on first using VREF.h).
  279. * BANDGAP, BANDGAP (switch on first using VREF.h).
  280. * VREFH, High VREF.
  281. * VREFL, Low VREF.
  282. * \param pin ADC_INTERNAL_SOURCE to read.
  283. * \param adc_num ADC_X ADC module
  284. * \return the value of the pin.
  285. */
  286. int analogRead(ADC_INTERNAL_SOURCE pin, int8_t adc_num = -1) __attribute__((always_inline))
  287. {
  288. return analogRead(static_cast<uint8_t>(pin), adc_num);
  289. }
  290. #if ADC_DIFF_PAIRS > 0
  291. //! Reads the differential analog value of two pins (pinP - pinN).
  292. /** It waits until the value is read and then returns the result.
  293. * This function is interrupt safe, so it will restore the adc to the state it was before being called
  294. * If more than one ADC exists, it will select the module with less workload, you can force a selection using
  295. * adc_num
  296. * \param pinP must be A10 or A12.
  297. * \param pinN must be A11 (if pinP=A10) or A13 (if pinP=A12).
  298. * \param adc_num ADC_X ADC module
  299. * \return the differential value of the pins, invalid pins return ADC_ERROR_VALUE.
  300. * If a comparison has been set up and fails, it will return ADC_ERROR_VALUE.
  301. */
  302. int analogReadDifferential(uint8_t pinP, uint8_t pinN, int8_t adc_num = -1);
  303. #endif
  304. /////////////// NON-BLOCKING CONVERSION METHODS //////////////
  305. //! Starts an analog measurement on the pin and enables interrupts.
  306. /** It returns immediately, get value with readSingle().
  307. * If this function interrupts a measurement, it stores the settings in adc_config
  308. * \param pin can be any of the analog pins
  309. * \param adc_num ADC_X ADC module
  310. * \return true if the pin is valid, false otherwise.
  311. */
  312. bool startSingleRead(uint8_t pin, int8_t adc_num = -1);
  313. #if ADC_DIFF_PAIRS > 0
  314. //! Start a differential conversion between two pins (pinP - pinN) and enables interrupts.
  315. /** It returns immediately, get value with readSingle().
  316. * If this function interrupts a measurement, it stores the settings in adc_config
  317. * \param pinP must be A10 or A12.
  318. * \param pinN must be A11 (if pinP=A10) or A13 (if pinP=A12).
  319. * \param adc_num ADC_X ADC module
  320. * \return true if the pins are valid, false otherwise.
  321. */
  322. bool startSingleDifferential(uint8_t pinP, uint8_t pinN, int8_t adc_num = -1);
  323. #endif
  324. //! Reads the analog value of a single conversion.
  325. /** Set the conversion with with startSingleRead(pin) or startSingleDifferential(pinP, pinN).
  326. * \param adc_num ADC_X ADC module
  327. * \return the converted value.
  328. */
  329. int readSingle(int8_t adc_num = -1);
  330. ///////////// CONTINUOUS CONVERSION METHODS ////////////
  331. //! Starts continuous conversion on the pin.
  332. /** It returns as soon as the ADC is set, use analogReadContinuous() to read the value.
  333. * \param pin can be any of the analog pins
  334. * \param adc_num ADC_X ADC module
  335. * \return true if the pin is valid, false otherwise.
  336. */
  337. bool startContinuous(uint8_t pin, int8_t adc_num = -1);
  338. #if ADC_DIFF_PAIRS > 0
  339. //! Starts continuous conversion between the pins (pinP-pinN).
  340. /** It returns as soon as the ADC is set, use analogReadContinuous() to read the value.
  341. * \param pinP must be A10 or A12.
  342. * \param pinN must be A11 (if pinP=A10) or A13 (if pinP=A12).
  343. * \param adc_num ADC_X ADC module
  344. * \return true if the pins are valid, false otherwise.
  345. */
  346. bool startContinuousDifferential(uint8_t pinP, uint8_t pinN, int8_t adc_num = -1);
  347. #endif
  348. //! Reads the analog value of a continuous conversion.
  349. /** Set the continuous conversion with with analogStartContinuous(pin) or startContinuousDifferential(pinP, pinN).
  350. * If single-ended and 16 bits it's necessary to typecast it to an unsigned type (like uint16_t),
  351. * otherwise values larger than 3.3/2 V are interpreted as negative!
  352. * \param adc_num ADC_X ADC module
  353. * \return the last converted value.
  354. */
  355. int analogReadContinuous(int8_t adc_num = -1);
  356. //! Stops continuous conversion
  357. /**
  358. * \param adc_num ADC_X ADC module
  359. */
  360. void stopContinuous(int8_t adc_num = -1);
  361. /////////// SYNCHRONIZED METHODS ///////////////
  362. ///// ONLY FOR BOARDS WITH MORE THAN ONE ADC /////
  363. #ifdef ADC_DUAL_ADCS
  364. //! Struct for synchronous measurements
  365. /** result_adc0 has the result from ADC0 and result_adc1 from ADC1.
  366. */
  367. struct Sync_result
  368. {
  369. int32_t result_adc0, result_adc1;
  370. };
  371. //////////////// SYNCHRONIZED BLOCKING METHODS //////////////////
  372. //! Returns the analog values of both pins, measured at the same time by the two ADC modules.
  373. /** It waits until the values are read and then returns the result as a struct Sync_result,
  374. * use Sync_result.result_adc0 and Sync_result.result_adc1.
  375. * If a comparison has been set up and fails, it will return ADC_ERROR_VALUE in both fields of the struct.
  376. * This function is interrupt safe, so it will restore the adc to the state it was before being called
  377. * \param pin0 pin in ADC0
  378. * \param pin1 pin in ADC1
  379. * \return a Sync_result struct with the result of each ADC value.
  380. */
  381. Sync_result analogSynchronizedRead(uint8_t pin0, uint8_t pin1);
  382. //! Same as analogSynchronizedRead
  383. /**
  384. * \param pin0 pin in ADC0
  385. * \param pin1 pin in ADC1
  386. * \return a Sync_result struct with the result of each ADC value.
  387. */
  388. Sync_result analogSyncRead(uint8_t pin0, uint8_t pin1) __attribute__((always_inline)) { return analogSynchronizedRead(pin0, pin1); }
  389. #if ADC_DIFF_PAIRS > 0
  390. //! Returns the differential analog values of both sets of pins, measured at the same time by the two ADC modules.
  391. /** It waits until the values are read and then returns the result as a struct Sync_result,
  392. * use Sync_result.result_adc0 and Sync_result.result_adc1.
  393. * If a comparison has been set up and fails, it will return ADC_ERROR_VALUE in both fields of the struct.
  394. * This function is interrupt safe, so it will restore the adc to the state it was before being called
  395. * \param pin0P positive pin in ADC0
  396. * \param pin0N negative pin in ADC0
  397. * \param pin1P positive pin in ADC1
  398. * \param pin1N negative pin in ADC1
  399. * \return a Sync_result struct with the result of each differential ADC value.
  400. */
  401. Sync_result analogSynchronizedReadDifferential(uint8_t pin0P, uint8_t pin0N, uint8_t pin1P, uint8_t pin1N);
  402. //! Same as analogSynchronizedReadDifferential
  403. /**
  404. * \param pin0P positive pin in ADC0
  405. * \param pin0N negative pin in ADC0
  406. * \param pin1P positive pin in ADC1
  407. * \param pin1N negative pin in ADC1
  408. * \return a Sync_result struct with the result of each differential ADC value.
  409. */
  410. Sync_result analogSyncReadDifferential(uint8_t pin0P, uint8_t pin0N, uint8_t pin1P, uint8_t pin1N) __attribute__((always_inline))
  411. {
  412. return analogSynchronizedReadDifferential(pin0P, pin0N, pin1P, pin1N);
  413. }
  414. #endif
  415. /////////////// SYNCHRONIZED NON-BLOCKING METHODS //////////////
  416. //! Starts an analog measurement at the same time on the two ADC modules
  417. /** It returns immediately, get value with readSynchronizedSingle().
  418. * If this function interrupts a measurement, it stores the settings in adc_config
  419. * \param pin0 pin in ADC0
  420. * \param pin1 pin in ADC1
  421. * \return true if the pins are valid, false otherwise.
  422. */
  423. bool startSynchronizedSingleRead(uint8_t pin0, uint8_t pin1);
  424. #if ADC_DIFF_PAIRS > 0
  425. //! Start a differential conversion between two pins (pin0P - pin0N) and (pin1P - pin1N)
  426. /** It returns immediately, get value with readSynchronizedSingle().
  427. * If this function interrupts a measurement, it stores the settings in adc_config
  428. * \param pin0P positive pin in ADC0
  429. * \param pin0N negative pin in ADC0
  430. * \param pin1P positive pin in ADC1
  431. * \param pin1N negative pin in ADC1
  432. * \return true if the pins are valid, false otherwise.
  433. */
  434. bool startSynchronizedSingleDifferential(uint8_t pin0P, uint8_t pin0N, uint8_t pin1P, uint8_t pin1N);
  435. #endif
  436. //! Reads the analog value of a single conversion.
  437. /**
  438. * \return the converted value.
  439. */
  440. Sync_result readSynchronizedSingle();
  441. ///////////// SYNCHRONIZED CONTINUOUS CONVERSION METHODS ////////////
  442. //! Starts a continuous conversion in both ADCs simultaneously
  443. /** Use readSynchronizedContinuous to get the values
  444. * \param pin0 pin in ADC0
  445. * \param pin1 pin in ADC1
  446. * \return true if the pins are valid, false otherwise.
  447. */
  448. bool startSynchronizedContinuous(uint8_t pin0, uint8_t pin1);
  449. #if ADC_DIFF_PAIRS > 0
  450. //! Starts a continuous differential conversion in both ADCs simultaneously
  451. /** Use readSynchronizedContinuous to get the values
  452. * \param pin0P positive pin in ADC0
  453. * \param pin0N negative pin in ADC0
  454. * \param pin1P positive pin in ADC1
  455. * \param pin1N negative pin in ADC1
  456. * \return true if the pins are valid, false otherwise.
  457. */
  458. bool startSynchronizedContinuousDifferential(uint8_t pin0P, uint8_t pin0N, uint8_t pin1P, uint8_t pin1N);
  459. #endif
  460. //! Returns the values of both ADCs.
  461. /**
  462. * \return the converted value.
  463. */
  464. Sync_result readSynchronizedContinuous();
  465. //! Stops synchronous continuous conversion
  466. void stopSynchronizedContinuous();
  467. #endif
  468. //////////// ERRORS /////
  469. //! Resets all errors from all ADCs, if any.
  470. void resetError()
  471. {
  472. for (int i = 0; i < ADC_NUM_ADCS; i++)
  473. {
  474. adc[i]->resetError();
  475. }
  476. }
  477. //! Translate pin number to SC1A nomenclature
  478. // should this be a constexpr?
  479. static const uint8_t channel2sc1aADC0[ADC_MAX_PIN + 1];
  480. #ifdef ADC_DUAL_ADCS
  481. //! Translate pin number to SC1A nomenclature
  482. static const uint8_t channel2sc1aADC1[ADC_MAX_PIN + 1];
  483. #endif
  484. //! Translate pin number to SC1A nomenclature for differential pins
  485. static const uint8_t sc1a2channelADC0[ADC_MAX_PIN + 1];
  486. #ifdef ADC_DUAL_ADCS
  487. //! Translate pin number to SC1A nomenclature for differential pins
  488. static const uint8_t sc1a2channelADC1[ADC_MAX_PIN + 1];
  489. #endif
  490. #if ADC_DIFF_PAIRS > 0
  491. //! Translate differential pin number to SC1A nomenclature
  492. static const ADC_Module::ADC_NLIST diff_table_ADC0[ADC_DIFF_PAIRS];
  493. #ifdef ADC_DUAL_ADCS
  494. //! Translate differential pin number to SC1A nomenclature
  495. static const ADC_Module::ADC_NLIST diff_table_ADC1[ADC_DIFF_PAIRS];
  496. #endif
  497. #endif
  498. };
  499. #ifdef __cplusplus
  500. }
  501. #endif
  502. #endif // ADC_H