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_Module.h 26KB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  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_Module.h: Declarations of the fuctions of a Teensy 3.x, LC ADC module
  26. *
  27. */
  28. /*! \page adc_module ADC Module
  29. Control each ADC_Module independently.
  30. See the ADC_Module class for all methods.
  31. */
  32. #ifndef ADC_MODULE_H
  33. #define ADC_MODULE_H
  34. #include <Arduino.h>
  35. #include <settings_defines.h>
  36. #include <atomic.h>
  37. using ADC_Error::ADC_ERROR;
  38. using namespace ADC_settings;
  39. // debug mode: blink the led light
  40. #define ADC_debug 0
  41. /** Class ADC_Module: Implements all functions of the Teensy 3.x, LC analog to digital converter
  42. *
  43. */
  44. class ADC_Module
  45. {
  46. public:
  47. #if ADC_DIFF_PAIRS > 0
  48. //! \cond internal
  49. //! Dictionary with the differential pins as keys and the SC1A number as values
  50. /** Internal, do not use.
  51. */
  52. struct ADC_NLIST
  53. {
  54. //! Pin and corresponding SC1A value.
  55. uint8_t pin, sc1a;
  56. };
  57. #endif
  58. //! \endcond
  59. #if ADC_DIFF_PAIRS > 0
  60. //! Constructor
  61. /** Pass the ADC number and the Channel number to SC1A number arrays.
  62. * \param ADC_number Number of the ADC module, from 0.
  63. * \param a_channel2sc1a contains an index that pairs each pin to its SC1A number (used to start a conversion on that pin)
  64. * \param a_diff_table is similar to a_channel2sc1a, but for differential pins.
  65. * \param a_adc_regs pointer to start of the ADC registers
  66. */
  67. ADC_Module(uint8_t ADC_number,
  68. const uint8_t *const a_channel2sc1a,
  69. const ADC_NLIST *const a_diff_table,
  70. ADC_REGS_t &a_adc_regs);
  71. #else
  72. //! Constructor
  73. /** Pass the ADC number and the Channel number to SC1A number arrays.
  74. * \param ADC_number Number of the ADC module, from 0.
  75. * \param a_channel2sc1a contains an index that pairs each pin to its SC1A number (used to start a conversion on that pin)
  76. * \param a_adc_regs pointer to start of the ADC registers
  77. */
  78. ADC_Module(uint8_t ADC_number,
  79. const uint8_t *const a_channel2sc1a,
  80. ADC_REGS_t &a_adc_regs);
  81. #endif
  82. //! Starts the calibration sequence, waits until it's done and writes the results
  83. /** Usually it's not necessary to call this function directly, but do it if the "environment" changed
  84. * significantly since the program was started.
  85. */
  86. void recalibrate();
  87. //! Starts the calibration sequence
  88. void calibrate();
  89. //! Waits until calibration is finished and writes the corresponding registers
  90. void wait_for_cal();
  91. /////////////// METHODS TO SET/GET SETTINGS OF THE ADC ////////////////////
  92. //! Set the voltage reference you prefer, default is vcc
  93. /*!
  94. * \param ref_type can be ADC_REFERENCE::REF_3V3, ADC_REFERENCE::REF_1V2 (not for Teensy LC) or ADC_REFERENCE::REF_EXT
  95. *
  96. * It recalibrates at the end.
  97. */
  98. void setReference(ADC_REFERENCE ref_type);
  99. //! Change the resolution of the measurement.
  100. /*!
  101. * \param bits is the number of bits of resolution.
  102. * For single-ended measurements: 8, 10, 12 or 16 bits.
  103. * For differential measurements: 9, 11, 13 or 16 bits.
  104. * If you want something in between (11 bits single-ended for example) select the immediate higher
  105. * and shift the result one to the right.
  106. *
  107. * Whenever you change the resolution, change also the comparison values (if you use them).
  108. */
  109. void setResolution(uint8_t bits);
  110. //! Returns the resolution of the ADC_Module.
  111. /**
  112. * \return the resolution of the ADC_Module.
  113. */
  114. uint8_t getResolution();
  115. //! Returns the maximum value for a measurement: 2^res-1.
  116. /**
  117. * \return the maximum value for a measurement: 2^res-1.
  118. */
  119. uint32_t getMaxValue();
  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. */
  138. void setConversionSpeed(ADC_CONVERSION_SPEED speed);
  139. //! Sets the sampling speed
  140. /** Increase the sampling speed for low impedance sources, decrease it for higher impedance ones.
  141. * \param speed can be any of the ADC_SAMPLING_SPEED enum: VERY_LOW_SPEED, LOW_SPEED, MED_SPEED, HIGH_SPEED or VERY_HIGH_SPEED.
  142. *
  143. * VERY_LOW_SPEED is the lowest possible sampling speed (+24 ADCK).
  144. * LOW_SPEED adds +16 ADCK.
  145. * MED_SPEED adds +10 ADCK.
  146. * HIGH_SPEED adds +6 ADCK.
  147. * VERY_HIGH_SPEED is the highest possible sampling speed (0 ADCK added).
  148. */
  149. void setSamplingSpeed(ADC_SAMPLING_SPEED speed);
  150. //! Set the number of averages
  151. /*!
  152. * \param num can be 0, 4, 8, 16 or 32.
  153. *
  154. * It doesn't recalibrate at the end.
  155. */
  156. void setAveraging(uint8_t num);
  157. //! Enable interrupts
  158. /** An IRQ_ADCx Interrupt will be raised when the conversion is completed
  159. * (including hardware averages and if the comparison (if any) is true).
  160. * \param isr function (returns void and accepts no arguments) that will be executed after an interrupt.
  161. * \param priority Interrupt priority, highest is 0, lowest is 255.
  162. */
  163. void enableInterrupts(void (*isr)(void), uint8_t priority = 255);
  164. //! Disable interrupts
  165. void disableInterrupts();
  166. #ifdef ADC_USE_DMA
  167. //! Enable DMA request
  168. /** An ADC DMA request will be raised when the conversion is completed
  169. * (including hardware averages and if the comparison (if any) is true).
  170. */
  171. void enableDMA();
  172. //! Disable ADC DMA request
  173. void disableDMA();
  174. #endif
  175. //! Enable the compare function to a single value
  176. /** A conversion will be completed only when the ADC value
  177. * is >= compValue (greaterThan=1) or < compValue (greaterThan=0)
  178. * Call it after changing the resolution
  179. * Use with interrupts or poll conversion completion with isComplete()
  180. * \param compValue value to compare
  181. * \param greaterThan true or false
  182. */
  183. void enableCompare(int16_t compValue, bool greaterThan);
  184. //! Enable the compare function to a range
  185. /** A conversion will be completed only when the ADC value is inside (insideRange=1) or outside (=0)
  186. * the range given by (lowerLimit, upperLimit),including (inclusive=1) the limits or not (inclusive=0).
  187. * See Table 31-78, p. 617 of the freescale manual.
  188. * Call it after changing the resolution
  189. * Use with interrupts or poll conversion completion with isComplete()
  190. * \param lowerLimit lower value to compare
  191. * \param upperLimit upper value to compare
  192. * \param insideRange true or false
  193. * \param inclusive true or false
  194. */
  195. void enableCompareRange(int16_t lowerLimit, int16_t upperLimit, bool insideRange, bool inclusive);
  196. //! Disable the compare function
  197. void disableCompare();
  198. #ifdef ADC_USE_PGA
  199. //! Enable and set PGA
  200. /** Enables the PGA and sets the gain
  201. * Use only for signals lower than 1.2 V and only in differential mode
  202. * \param gain can be 1, 2, 4, 8, 16, 32 or 64
  203. */
  204. void enablePGA(uint8_t gain);
  205. //! Returns the PGA level
  206. /**
  207. * \return PGA level from 1 to 64
  208. */
  209. uint8_t getPGA();
  210. //! Disable PGA
  211. void disablePGA();
  212. #endif
  213. //! Set continuous conversion mode
  214. void continuousMode() __attribute__((always_inline))
  215. {
  216. #ifdef ADC_TEENSY_4
  217. atomic::setBitFlag(adc_regs.GC, ADC_GC_ADCO);
  218. #else
  219. atomic::setBitFlag(adc_regs.SC3, ADC_SC3_ADCO);
  220. #endif
  221. }
  222. //! Set single-shot conversion mode
  223. void singleMode() __attribute__((always_inline))
  224. {
  225. #ifdef ADC_TEENSY_4
  226. atomic::clearBitFlag(adc_regs.GC, ADC_GC_ADCO);
  227. #else
  228. atomic::clearBitFlag(adc_regs.SC3, ADC_SC3_ADCO);
  229. #endif
  230. }
  231. //! Set single-ended conversion mode
  232. void singleEndedMode() __attribute__((always_inline))
  233. {
  234. #ifdef ADC_TEENSY_4
  235. // Teensy 4 is always single-ended
  236. #else
  237. atomic::clearBitFlag(adc_regs.SC1A, ADC_SC1_DIFF);
  238. #endif
  239. }
  240. #if ADC_DIFF_PAIRS > 0
  241. //! Set differential conversion mode
  242. void differentialMode() __attribute__((always_inline))
  243. {
  244. atomic::setBitFlag(adc_regs.SC1A, ADC_SC1_DIFF);
  245. }
  246. #endif
  247. //! Use software to trigger the ADC, this is the most common setting
  248. void setSoftwareTrigger() __attribute__((always_inline))
  249. {
  250. #ifdef ADC_TEENSY_4
  251. atomic::clearBitFlag(adc_regs.CFG, ADC_CFG_ADTRG);
  252. #else
  253. atomic::clearBitFlag(adc_regs.SC2, ADC_SC2_ADTRG);
  254. #endif
  255. }
  256. //! Use hardware to trigger the ADC
  257. void setHardwareTrigger() __attribute__((always_inline))
  258. {
  259. #ifdef ADC_TEENSY_4
  260. atomic::setBitFlag(adc_regs.CFG, ADC_CFG_ADTRG);
  261. #else
  262. atomic::setBitFlag(adc_regs.SC2, ADC_SC2_ADTRG);
  263. #endif
  264. }
  265. ////////////// INFORMATION ABOUT THE STATE OF THE ADC /////////////////
  266. //! Is the ADC converting at the moment?
  267. /**
  268. * \return true or false
  269. */
  270. volatile bool isConverting() __attribute__((always_inline))
  271. {
  272. #ifdef ADC_TEENSY_4
  273. return atomic::getBitFlag(adc_regs.GS, ADC_GS_ADACT);
  274. #else
  275. //return (ADC_SC2_adact);
  276. return atomic::getBitFlag(adc_regs.SC2, ADC_SC2_ADACT);
  277. //return ((adc_regs.SC2) & ADC_SC2_ADACT) >> 7;
  278. #endif
  279. }
  280. //! Is an ADC conversion ready?
  281. /**
  282. * \return true if yes, false if not.
  283. * When a value is read this function returns false until a new value exists,
  284. * so it only makes sense to call it before analogReadContinuous() or readSingle()
  285. */
  286. volatile bool isComplete() __attribute__((always_inline))
  287. {
  288. #ifdef ADC_TEENSY_4
  289. return atomic::getBitFlag(adc_regs.HS, ADC_HS_COCO0);
  290. #else
  291. //return (ADC_SC1A_coco);
  292. return atomic::getBitFlag(adc_regs.SC1A, ADC_SC1_COCO);
  293. //return ((adc_regs.SC1A) & ADC_SC1_COCO) >> 7;
  294. #endif
  295. }
  296. #if ADC_DIFF_PAIRS > 0
  297. //! Is the ADC in differential mode?
  298. /**
  299. * \return true or false
  300. */
  301. volatile bool isDifferential() __attribute__((always_inline))
  302. {
  303. //return ((adc_regs.SC1A) & ADC_SC1_DIFF) >> 5;
  304. return atomic::getBitFlag(adc_regs.SC1A, ADC_SC1_DIFF);
  305. }
  306. #endif
  307. //! Is the ADC in continuous mode?
  308. /**
  309. * \return true or false
  310. */
  311. volatile bool isContinuous() __attribute__((always_inline))
  312. {
  313. #ifdef ADC_TEENSY_4
  314. return atomic::getBitFlag(adc_regs.GC, ADC_GC_ADCO);
  315. #else
  316. //return (ADC_SC3_adco);
  317. return atomic::getBitFlag(adc_regs.SC3, ADC_SC3_ADCO);
  318. //return ((adc_regs.SC3) & ADC_SC3_ADCO) >> 3;
  319. #endif
  320. }
  321. #ifdef ADC_USE_PGA
  322. //! Is the PGA function enabled?
  323. /**
  324. * \return true or false
  325. */
  326. volatile bool isPGAEnabled() __attribute__((always_inline))
  327. {
  328. return atomic::getBitFlag(adc_regs.PGA, ADC_PGA_PGAEN);
  329. }
  330. #endif
  331. //////////////// INFORMATION ABOUT VALID PINS //////////////////
  332. //! Check whether the pin is a valid analog pin
  333. /**
  334. * \param pin to check.
  335. * \return true if the pin is valid, false otherwise.
  336. */
  337. bool checkPin(uint8_t pin);
  338. //! Check whether the pins are a valid analog differential pair of pins
  339. /** If PGA is enabled it also checks that this ADCx can use PGA on this pins
  340. * \param pinP positive pin to check.
  341. * \param pinN negative pin to check.
  342. * \return true if the pin is valid, false otherwise.
  343. */
  344. bool checkDifferentialPins(uint8_t pinP, uint8_t pinN);
  345. //////////////// HELPER METHODS FOR CONVERSION /////////////////
  346. //! Starts a single-ended conversion on the pin
  347. /** It sets the mux correctly, doesn't do any of the checks on the pin and
  348. * doesn't change the continuous conversion bit.
  349. * \param pin to read.
  350. */
  351. void startReadFast(uint8_t pin); // helper method
  352. #if ADC_DIFF_PAIRS > 0
  353. //! Starts a differential conversion on the pair of pins
  354. /** It sets the mux correctly, doesn't do any of the checks on the pin and
  355. * doesn't change the continuous conversion bit.
  356. * \param pinP positive pin to read.
  357. * \param pinN negative pin to read.
  358. */
  359. void startDifferentialFast(uint8_t pinP, uint8_t pinN);
  360. #endif
  361. //////////////// BLOCKING CONVERSION METHODS //////////////////
  362. //! Returns the analog value of the pin.
  363. /** It waits until the value is read and then returns the result.
  364. * If a comparison has been set up and fails, it will return ADC_ERROR_VALUE.
  365. * This function is interrupt safe, so it will restore the adc to the state it was before being called
  366. * \param pin pin to read.
  367. * \return the value of the pin.
  368. */
  369. int analogRead(uint8_t pin);
  370. //! Returns the analog value of the special internal source, such as the temperature sensor.
  371. /** It calls analogRead(uint8_t pin) internally, with the correct value for the pin for all boards.
  372. * Possible values:
  373. * TEMP_SENSOR, Temperature sensor.
  374. * VREF_OUT, 1.2 V reference (switch on first using VREF.h).
  375. * BANDGAP, BANDGAP (switch on first using VREF.h).
  376. * VREFH, High VREF.
  377. * VREFL, Low VREF.
  378. * \param pin ADC_INTERNAL_SOURCE to read.
  379. * \return the value of the pin.
  380. */
  381. int analogRead(ADC_INTERNAL_SOURCE pin) __attribute__((always_inline))
  382. {
  383. return analogRead(static_cast<uint8_t>(pin));
  384. }
  385. #if ADC_DIFF_PAIRS > 0
  386. //! Reads the differential analog value of two pins (pinP - pinN).
  387. /** It waits until the value is read and then returns the result.
  388. * If a comparison has been set up and fails, it will return ADC_ERROR_DIFF_VALUE.
  389. * \param pinP must be A10 or A12.
  390. * \param pinN must be A11 (if pinP=A10) or A13 (if pinP=A12).
  391. * \return the difference between the pins if they are valid, othewise returns ADC_ERROR_DIFF_VALUE.
  392. * This function is interrupt safe, so it will restore the adc to the state it was before being called
  393. */
  394. int analogReadDifferential(uint8_t pinP, uint8_t pinN);
  395. #endif
  396. /////////////// NON-BLOCKING CONVERSION METHODS //////////////
  397. //! Starts an analog measurement on the pin and enables interrupts.
  398. /** It returns immediately, get value with readSingle().
  399. * If this function interrupts a measurement, it stores the settings in adc_config
  400. * \param pin pin to read.
  401. * \return true if the pin is valid, false otherwise.
  402. */
  403. bool startSingleRead(uint8_t pin);
  404. #if ADC_DIFF_PAIRS > 0
  405. //! Start a differential conversion between two pins (pinP - pinN) and enables interrupts.
  406. /** It returns immediately, get value with readSingle().
  407. * If this function interrupts a measurement, it stores the settings in adc_config
  408. * \param pinP must be A10 or A12.
  409. * \param pinN must be A11 (if pinP=A10) or A13 (if pinP=A12).
  410. * \return true if the pins are valid, false otherwise.
  411. */
  412. bool startSingleDifferential(uint8_t pinP, uint8_t pinN);
  413. #endif
  414. //! Reads the analog value of a single conversion.
  415. /** Set the conversion with with startSingleRead(pin) or startSingleDifferential(pinP, pinN).
  416. * \return the converted value.
  417. */
  418. int readSingle() __attribute__((always_inline))
  419. {
  420. return analogReadContinuous();
  421. }
  422. ///////////// CONTINUOUS CONVERSION METHODS ////////////
  423. //! Starts continuous conversion on the pin.
  424. /** It returns as soon as the ADC is set, use analogReadContinuous() to read the value.
  425. * \param pin can be any of the analog pins
  426. * \return true if the pin is valid, false otherwise.
  427. */
  428. bool startContinuous(uint8_t pin);
  429. #if ADC_DIFF_PAIRS > 0
  430. //! Starts continuous conversion between the pins (pinP-pinN).
  431. /** It returns as soon as the ADC is set, use analogReadContinuous() to read the value.
  432. * \param pinP must be A10 or A12.
  433. * \param pinN must be A11 (if pinP=A10) or A13 (if pinP=A12).
  434. * \return true if the pins are valid, false otherwise.
  435. */
  436. bool startContinuousDifferential(uint8_t pinP, uint8_t pinN);
  437. #endif
  438. //! Reads the analog value of a continuous conversion.
  439. /** Set the continuous conversion with with analogStartContinuous(pin) or startContinuousDifferential(pinP, pinN).
  440. * \return the last converted value.
  441. * If single-ended and 16 bits it's necessary to typecast it to an unsigned type (like uint16_t),
  442. * otherwise values larger than 3.3/2 V are interpreted as negative!
  443. */
  444. int analogReadContinuous() __attribute__((always_inline))
  445. {
  446. #ifdef ADC_TEENSY_4
  447. return (int16_t)(int32_t)adc_regs.R0;
  448. #else
  449. return (int16_t)(int32_t)adc_regs.RA;
  450. #endif
  451. }
  452. //! Stops continuous conversion
  453. void stopContinuous();
  454. //////////// FREQUENCY METHODS ////////
  455. // The general API is:
  456. // void startTimer(uint32_t freq)
  457. // void stopTimer()
  458. // uint32_t getTimerFrequency()
  459. // For each board the best timer method will be selected
  460. //////////// PDB ////////////////
  461. //// Only works for Teensy 3.x not LC nor Tensy 4.0 (they don't have PDB)
  462. #if defined(ADC_USE_PDB)
  463. //! Start the default timer (PDB) triggering the ADC at the frequency
  464. /** The default timer in this board is the PDB, you can also call it directly with startPDB().
  465. * Call startSingleRead or startSingleDifferential on the pin that you want to measure before calling this function.
  466. * See the example adc_pdb.ino.
  467. * \param freq is the frequency of the ADC conversion, it can't be lower that 1 Hz
  468. */
  469. void startTimer(uint32_t freq) __attribute__((always_inline)) { startPDB(freq); }
  470. //! Start PDB triggering the ADC at the frequency
  471. /** Call startSingleRead or startSingleDifferential on the pin that you want to measure before calling this function.
  472. * See the example adc_pdb.ino.
  473. * \param freq is the frequency of the ADC conversion, it can't be lower that 1 Hz
  474. */
  475. void startPDB(uint32_t freq);
  476. //! Stop the default timer (PDB)
  477. void stopTimer() __attribute__((always_inline)) { stopPDB(); }
  478. //! Stop the PDB
  479. void stopPDB();
  480. //! Return the default timer's (PDB) frequency
  481. /** The default timer in this board is the PDB, you can also call it directly with getPDBFrequency().
  482. * \return the timer's frequency in Hz.
  483. */
  484. uint32_t getTimerFrequency() __attribute__((always_inline)) { return getPDBFrequency(); }
  485. //! Return the PDB's frequency
  486. /** Return the PDB's frequency
  487. * \return the timer's frequency in Hz.
  488. */
  489. uint32_t getPDBFrequency();
  490. //////////// TIMER ////////////////
  491. //// Only works for Teensy 3.x and 4 (not LC)
  492. #elif defined(ADC_USE_QUAD_TIMER)
  493. //! Start the default timer (QuadTimer) triggering the ADC at the frequency
  494. /** The default timer in this board is the QuadTimer, you can also call it directly with startQuadTimer().
  495. * Call startSingleRead or startSingleDifferential on the pin that you want to measure before calling this function.
  496. * See the example adc_timer.ino.
  497. * \param freq is the frequency of the ADC conversion, it can't be lower that 1 Hz
  498. */
  499. void startTimer(uint32_t freq) __attribute__((always_inline)) { startQuadTimer(freq); }
  500. //! Start a Quad timer to trigger the ADC at the frequency
  501. /** Call startSingleRead or startSingleDifferential on the pin that you want to measure before calling this function.
  502. * See the example adc_timer.ino.
  503. * \param freq is the frequency of the ADC conversion, it can't be lower that 1 Hz
  504. */
  505. void startQuadTimer(uint32_t freq);
  506. //! Stop the default timer (QuadTimer)
  507. void stopTimer() __attribute__((always_inline)) { stopQuadTimer(); }
  508. //! Stop the Quad timer
  509. void stopQuadTimer();
  510. //! Return the default timer's (QuadTimer) frequency
  511. /** The default timer in this board is the QuadTimer, you can also call it directly with getQuadTimerFrequency().
  512. * \return the timer's frequency in Hz.
  513. */
  514. uint32_t getTimerFrequency() __attribute__((always_inline)) { return getQuadTimerFrequency(); }
  515. //! Return the Quad timer's frequency
  516. /** Return the Quad timer's frequency
  517. * \return the timer's frequency in Hz.
  518. */
  519. uint32_t getQuadTimerFrequency();
  520. #endif
  521. //////// OTHER STUFF ///////////
  522. //! Store the config of the adc
  523. struct ADC_Config
  524. {
  525. //! ADC registers
  526. #ifdef ADC_TEENSY_4
  527. uint32_t savedHC0, savedCFG, savedGC, savedGS;
  528. #else
  529. uint32_t savedSC1A, savedSC2, savedSC3, savedCFG1, savedCFG2;
  530. #endif
  531. } adc_config;
  532. //! Was the adc in use before a call?
  533. uint8_t adcWasInUse;
  534. /** Save config of the ADC to the ADC_Config struct
  535. * \param config ADC_Config where the config will be stored
  536. */
  537. void saveConfig(ADC_Config *config)
  538. {
  539. #ifdef ADC_TEENSY_4
  540. config->savedHC0 = adc_regs.HC0;
  541. config->savedCFG = adc_regs.CFG;
  542. config->savedGC = adc_regs.GC;
  543. config->savedGS = adc_regs.GS;
  544. #else
  545. config->savedSC1A = adc_regs.SC1A;
  546. config->savedCFG1 = adc_regs.CFG1;
  547. config->savedCFG2 = adc_regs.CFG2;
  548. config->savedSC2 = adc_regs.SC2;
  549. config->savedSC3 = adc_regs.SC3;
  550. #endif
  551. }
  552. /** Load config to the ADC
  553. * \param config ADC_Config from where the config will be loaded
  554. */
  555. void loadConfig(const ADC_Config *config)
  556. {
  557. #ifdef ADC_TEENSY_4
  558. adc_regs.HC0 = config->savedHC0;
  559. adc_regs.CFG = config->savedCFG;
  560. adc_regs.GC = config->savedGC;
  561. adc_regs.GS = config->savedGS;
  562. #else
  563. adc_regs.CFG1 = config->savedCFG1;
  564. adc_regs.CFG2 = config->savedCFG2;
  565. adc_regs.SC2 = config->savedSC2;
  566. adc_regs.SC3 = config->savedSC3;
  567. adc_regs.SC1A = config->savedSC1A; // restore last
  568. #endif
  569. }
  570. //! Number of measurements that the ADC is performing
  571. uint8_t num_measurements;
  572. //! This flag indicates that some kind of error took place
  573. /** Use the defines at the beginning of this file to find out what caused the fail.
  574. */
  575. volatile ADC_ERROR fail_flag;
  576. //! Resets all errors from the ADC, if any.
  577. void resetError()
  578. {
  579. ADC_Error::resetError(fail_flag);
  580. }
  581. //! Which adc is this?
  582. const uint8_t ADC_num;
  583. private:
  584. // is set to 1 when the calibration procedure is taking place
  585. uint8_t calibrating;
  586. // the first calibration will use 32 averages and lowest speed,
  587. // when this calibration is over the averages and speed will be set to default.
  588. uint8_t init_calib;
  589. // resolution
  590. uint8_t analog_res_bits;
  591. // maximum value possible 2^res-1
  592. uint32_t analog_max_val;
  593. // num of averages
  594. uint8_t analog_num_average;
  595. // reference can be internal or external
  596. ADC_REF_SOURCE analog_reference_internal;
  597. #ifdef ADC_USE_PGA
  598. // value of the pga
  599. uint8_t pga_value;
  600. #endif
  601. // conversion speed
  602. ADC_CONVERSION_SPEED conversion_speed;
  603. // sampling speed
  604. ADC_SAMPLING_SPEED sampling_speed;
  605. // translate pin number to SC1A nomenclature
  606. const uint8_t *const channel2sc1a;
  607. // are interrupts on?
  608. bool interrupts_enabled;
  609. // same for differential pins
  610. #if ADC_DIFF_PAIRS > 0
  611. const ADC_NLIST *const diff_table;
  612. //! Get the SC1A value of the differential pair for this pin
  613. uint8_t getDifferentialPair(uint8_t pin)
  614. {
  615. for (uint8_t i = 0; i < ADC_DIFF_PAIRS; i++)
  616. {
  617. if (diff_table[i].pin == pin)
  618. {
  619. return diff_table[i].sc1a;
  620. }
  621. }
  622. return ADC_SC1A_PIN_INVALID;
  623. }
  624. #endif
  625. //! Initialize ADC
  626. void analog_init();
  627. //! Switch on clock to ADC
  628. void startClock()
  629. {
  630. #if defined(ADC_TEENSY_4)
  631. if (ADC_num == 0)
  632. {
  633. CCM_CCGR1 |= CCM_CCGR1_ADC1(CCM_CCGR_ON);
  634. }
  635. else
  636. {
  637. CCM_CCGR1 |= CCM_CCGR1_ADC2(CCM_CCGR_ON);
  638. }
  639. #else
  640. if (ADC_num == 0)
  641. {
  642. SIM_SCGC6 |= SIM_SCGC6_ADC0;
  643. }
  644. else
  645. {
  646. SIM_SCGC3 |= SIM_SCGC3_ADC1;
  647. }
  648. #endif
  649. }
  650. // registers point to the correct ADC module
  651. typedef volatile uint32_t &reg;
  652. // registers that control the adc module
  653. ADC_REGS_t &adc_regs;
  654. #ifdef ADC_USE_PDB
  655. reg PDB0_CHnC1; // PDB channel 0 or 1
  656. #endif
  657. #ifdef ADC_TEENSY_4
  658. uint8_t XBAR_IN;
  659. uint8_t XBAR_OUT;
  660. uint8_t QTIMER4_INDEX;
  661. uint8_t ADC_ETC_TRIGGER_INDEX;
  662. #endif
  663. const IRQ_NUMBER_t IRQ_ADC; // IRQ number
  664. protected:
  665. };
  666. #endif // ADC_MODULE_H