Teensy 4.1 core updated for 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.

analog.c 16KB

9 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
11 jaren geleden
9 jaren geleden
9 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2013 PJRC.COM, LLC.
  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. * 1. The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * 2. If the Software is incorporated into a build system that allows
  17. * selection among a list of target devices, then similar target
  18. * devices manufactured by PJRC.COM must be included in the list of
  19. * target devices and selectable in the same manner.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  25. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  26. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  27. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. * SOFTWARE.
  29. */
  30. #include "core_pins.h"
  31. //#include "HardwareSerial.h"
  32. #if defined(__MK64FX512__) || defined(__MK66FX1M0__) // ugly hack for now...
  33. #define __MK20DX256__
  34. #endif
  35. static uint8_t calibrating;
  36. static uint8_t analog_right_shift = 0;
  37. static uint8_t analog_config_bits = 10;
  38. static uint8_t analog_num_average = 4;
  39. static uint8_t analog_reference_internal = 0;
  40. // the alternate clock is connected to OSCERCLK (16 MHz).
  41. // datasheet says ADC clock should be 2 to 12 MHz for 16 bit mode
  42. // datasheet says ADC clock should be 1 to 18 MHz for 8-12 bit mode
  43. #if F_BUS == 60000000
  44. #define ADC_CFG1_16BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 7.5 MHz
  45. #define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 15 MHz
  46. #define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 15 MHz
  47. #define ADC_CFG1_8BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 15 MHz
  48. #elif F_BUS == 56000000
  49. #define ADC_CFG1_16BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 7 MHz
  50. #define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 14 MHz
  51. #define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 14 MHz
  52. #define ADC_CFG1_8BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 14 MHz
  53. #elif F_BUS == 48000000
  54. #define ADC_CFG1_16BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 12 MHz
  55. #define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 12 MHz
  56. #define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 12 MHz
  57. #define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1) // 24 MHz
  58. #elif F_BUS == 40000000
  59. #define ADC_CFG1_16BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 10 MHz
  60. #define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 10 MHz
  61. #define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 10 MHz
  62. #define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1) // 20 MHz
  63. #elif F_BUS == 36000000
  64. #define ADC_CFG1_16BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 9 MHz
  65. #define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1) // 18 MHz
  66. #define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1) // 18 MHz
  67. #define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1) // 18 MHz
  68. #elif F_BUS == 24000000
  69. #define ADC_CFG1_16BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0) // 12 MHz
  70. #define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0) // 12 MHz
  71. #define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0) // 12 MHz
  72. #define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 24 MHz
  73. #elif F_BUS == 16000000
  74. #define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
  75. #define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
  76. #define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
  77. #define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 16 MHz
  78. #elif F_BUS == 8000000
  79. #define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
  80. #define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
  81. #define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
  82. #define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
  83. #elif F_BUS == 4000000
  84. #define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz
  85. #define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz
  86. #define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz
  87. #define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz
  88. #elif F_BUS == 2000000
  89. #define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 2 MHz
  90. #define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 2 MHz
  91. #define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 2 MHz
  92. #define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 2 MHz
  93. #else
  94. #error "F_BUS must be 60, 56, 48, 40, 36, 24, 4 or 2 MHz"
  95. #endif
  96. void analog_init(void)
  97. {
  98. uint32_t num;
  99. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  100. VREF_TRM = 0x60;
  101. VREF_SC = 0xE1; // enable 1.2 volt ref
  102. #endif
  103. if (analog_config_bits == 8) {
  104. ADC0_CFG1 = ADC_CFG1_8BIT + ADC_CFG1_MODE(0);
  105. ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
  106. #if defined(__MK20DX256__)
  107. ADC1_CFG1 = ADC_CFG1_8BIT + ADC_CFG1_MODE(0);
  108. ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
  109. #endif
  110. } else if (analog_config_bits == 10) {
  111. ADC0_CFG1 = ADC_CFG1_10BIT + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP;
  112. ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
  113. #if defined(__MK20DX256__)
  114. ADC1_CFG1 = ADC_CFG1_10BIT + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP;
  115. ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
  116. #endif
  117. } else if (analog_config_bits == 12) {
  118. ADC0_CFG1 = ADC_CFG1_12BIT + ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP;
  119. ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
  120. #if defined(__MK20DX256__)
  121. ADC1_CFG1 = ADC_CFG1_12BIT + ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP;
  122. ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
  123. #endif
  124. } else {
  125. ADC0_CFG1 = ADC_CFG1_16BIT + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP;
  126. ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
  127. #if defined(__MK20DX256__)
  128. ADC1_CFG1 = ADC_CFG1_16BIT + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP;
  129. ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
  130. #endif
  131. }
  132. #if defined(__MK20DX128__)
  133. if (analog_reference_internal) {
  134. ADC0_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref
  135. } else {
  136. ADC0_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref
  137. }
  138. #elif defined(__MK20DX256__)
  139. if (analog_reference_internal) {
  140. ADC0_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref
  141. ADC1_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref
  142. } else {
  143. ADC0_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref
  144. ADC1_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref
  145. }
  146. #elif defined(__MKL26Z64__)
  147. if (analog_reference_internal) {
  148. ADC0_SC2 = ADC_SC2_REFSEL(0); // external AREF
  149. } else {
  150. ADC0_SC2 = ADC_SC2_REFSEL(1); // vcc
  151. }
  152. #endif
  153. num = analog_num_average;
  154. if (num <= 1) {
  155. ADC0_SC3 = ADC_SC3_CAL; // begin cal
  156. #if defined(__MK20DX256__)
  157. ADC1_SC3 = ADC_SC3_CAL; // begin cal
  158. #endif
  159. } else if (num <= 4) {
  160. ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(0);
  161. #if defined(__MK20DX256__)
  162. ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(0);
  163. #endif
  164. } else if (num <= 8) {
  165. ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(1);
  166. #if defined(__MK20DX256__)
  167. ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(1);
  168. #endif
  169. } else if (num <= 16) {
  170. ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(2);
  171. #if defined(__MK20DX256__)
  172. ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(2);
  173. #endif
  174. } else {
  175. ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(3);
  176. #if defined(__MK20DX256__)
  177. ADC1_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(3);
  178. #endif
  179. }
  180. calibrating = 1;
  181. }
  182. static void wait_for_cal(void)
  183. {
  184. uint16_t sum;
  185. //serial_print("wait_for_cal\n");
  186. #if defined(__MK20DX128__)
  187. while (ADC0_SC3 & ADC_SC3_CAL) {
  188. // wait
  189. }
  190. #elif defined(__MK20DX256__)
  191. while ((ADC0_SC3 & ADC_SC3_CAL) || (ADC1_SC3 & ADC_SC3_CAL)) {
  192. // wait
  193. }
  194. #endif
  195. __disable_irq();
  196. if (calibrating) {
  197. //serial_print("\n");
  198. sum = ADC0_CLPS + ADC0_CLP4 + ADC0_CLP3 + ADC0_CLP2 + ADC0_CLP1 + ADC0_CLP0;
  199. sum = (sum / 2) | 0x8000;
  200. ADC0_PG = sum;
  201. //serial_print("ADC0_PG = ");
  202. //serial_phex16(sum);
  203. //serial_print("\n");
  204. sum = ADC0_CLMS + ADC0_CLM4 + ADC0_CLM3 + ADC0_CLM2 + ADC0_CLM1 + ADC0_CLM0;
  205. sum = (sum / 2) | 0x8000;
  206. ADC0_MG = sum;
  207. //serial_print("ADC0_MG = ");
  208. //serial_phex16(sum);
  209. //serial_print("\n");
  210. #if defined(__MK20DX256__)
  211. sum = ADC1_CLPS + ADC1_CLP4 + ADC1_CLP3 + ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0;
  212. sum = (sum / 2) | 0x8000;
  213. ADC1_PG = sum;
  214. sum = ADC1_CLMS + ADC1_CLM4 + ADC1_CLM3 + ADC1_CLM2 + ADC1_CLM1 + ADC1_CLM0;
  215. sum = (sum / 2) | 0x8000;
  216. ADC1_MG = sum;
  217. #endif
  218. calibrating = 0;
  219. }
  220. __enable_irq();
  221. }
  222. // ADCx_SC2[REFSEL] bit selects the voltage reference sources for ADC.
  223. // VREFH/VREFL - connected as the primary reference option
  224. // 1.2 V VREF_OUT - connected as the VALT reference option
  225. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  226. #define DEFAULT 0
  227. #define INTERNAL 2
  228. #define INTERNAL1V2 2
  229. #define INTERNAL1V1 2
  230. #define EXTERNAL 0
  231. #elif defined(__MKL26Z64__)
  232. #define DEFAULT 0
  233. #define INTERNAL 0
  234. #define EXTERNAL 1
  235. #endif
  236. void analogReference(uint8_t type)
  237. {
  238. if (type) {
  239. // internal reference requested
  240. if (!analog_reference_internal) {
  241. analog_reference_internal = 1;
  242. if (calibrating) {
  243. ADC0_SC3 = 0; // cancel cal
  244. #if defined(__MK20DX256__)
  245. ADC1_SC3 = 0; // cancel cal
  246. #endif
  247. }
  248. analog_init();
  249. }
  250. } else {
  251. // vcc or external reference requested
  252. if (analog_reference_internal) {
  253. analog_reference_internal = 0;
  254. if (calibrating) {
  255. ADC0_SC3 = 0; // cancel cal
  256. #if defined(__MK20DX256__)
  257. ADC1_SC3 = 0; // cancel cal
  258. #endif
  259. }
  260. analog_init();
  261. }
  262. }
  263. }
  264. void analogReadRes(unsigned int bits)
  265. {
  266. unsigned int config;
  267. if (bits >= 13) {
  268. if (bits > 16) bits = 16;
  269. config = 16;
  270. } else if (bits >= 11) {
  271. config = 12;
  272. } else if (bits >= 9) {
  273. config = 10;
  274. } else {
  275. config = 8;
  276. }
  277. analog_right_shift = config - bits;
  278. if (config != analog_config_bits) {
  279. analog_config_bits = config;
  280. if (calibrating) ADC0_SC3 = 0; // cancel cal
  281. analog_init();
  282. }
  283. }
  284. void analogReadAveraging(unsigned int num)
  285. {
  286. if (calibrating) wait_for_cal();
  287. if (num <= 1) {
  288. num = 0;
  289. ADC0_SC3 = 0;
  290. } else if (num <= 4) {
  291. num = 4;
  292. ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(0);
  293. } else if (num <= 8) {
  294. num = 8;
  295. ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(1);
  296. } else if (num <= 16) {
  297. num = 16;
  298. ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(2);
  299. } else {
  300. num = 32;
  301. ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(3);
  302. }
  303. analog_num_average = num;
  304. }
  305. // The SC1A register is used for both software and hardware trigger modes of operation.
  306. #if defined(__MK20DX128__)
  307. static const uint8_t channel2sc1a[] = {
  308. 5, 14, 8, 9, 13, 12, 6, 7, 15, 4,
  309. 0, 19, 3, 21, 26, 22, 23
  310. };
  311. #elif defined(__MK20DX256__)
  312. static const uint8_t channel2sc1a[] = {
  313. 5, 14, 8, 9, 13, 12, 6, 7, 15, 4,
  314. 0, 19, 3, 19+128, 26, 18+128, 23,
  315. 5+192, 5+128, 4+128, 6+128, 7+128, 4+192
  316. // A15 26 E1 ADC1_SE5a 5+64
  317. // A16 27 C9 ADC1_SE5b 5
  318. // A17 28 C8 ADC1_SE4b 4
  319. // A18 29 C10 ADC1_SE6b 6
  320. // A19 30 C11 ADC1_SE7b 7
  321. // A20 31 E0 ADC1_SE4a 4+64
  322. };
  323. #elif defined(__MKL26Z64__)
  324. static const uint8_t channel2sc1a[] = {
  325. 5, 14, 8, 9, 13, 12, 6, 7, 15, 11,
  326. 0, 4+64, 23, 26, 27
  327. };
  328. #endif
  329. // TODO: perhaps this should store the NVIC priority, so it works recursively?
  330. static volatile uint8_t analogReadBusyADC0 = 0;
  331. #if defined(__MK20DX256__)
  332. static volatile uint8_t analogReadBusyADC1 = 0;
  333. #endif
  334. int analogRead(uint8_t pin)
  335. {
  336. int result;
  337. uint8_t index, channel;
  338. //serial_phex(pin);
  339. //serial_print(" ");
  340. #if defined(__MK20DX128__)
  341. if (pin <= 13) {
  342. index = pin; // 0-13 refer to A0-A13
  343. } else if (pin <= 23) {
  344. index = pin - 14; // 14-23 are A0-A9
  345. } else if (pin >= 34 && pin <= 40) {
  346. index = pin - 24; // 34-37 are A10-A13, 38 is temp sensor,
  347. // 39 is vref, 40 is unused analog pin
  348. } else {
  349. return 0;
  350. }
  351. #elif defined(__MK20DX256__)
  352. if (pin <= 13) {
  353. index = pin; // 0-13 refer to A0-A13
  354. } else if (pin <= 23) {
  355. index = pin - 14; // 14-23 are A0-A9
  356. } else if (pin >= 26 && pin <= 31) {
  357. index = pin - 9; // 26-31 are A15-A20
  358. } else if (pin >= 34 && pin <= 40) {
  359. index = pin - 24; // 34-37 are A10-A13, 38 is temp sensor,
  360. // 39 is vref, 40 is A14
  361. } else {
  362. return 0;
  363. }
  364. #elif defined(__MKL26Z64__)
  365. if (pin <= 12) {
  366. index = pin; // 0-12 refer to A0-A12
  367. } else if (pin >= 14 && pin <= 26) {
  368. index = pin - 14; // 14-26 are A0-A12
  369. } else if (pin >= 38 && pin <= 39) {
  370. index = pin - 25; // 38=temperature
  371. // 39=bandgap ref (PMC_REGSC |= PMC_REGSC_BGBE)
  372. } else {
  373. return 0;
  374. }
  375. #endif
  376. //serial_phex(index);
  377. //serial_print(" ");
  378. channel = channel2sc1a[index];
  379. //serial_phex(channel);
  380. //serial_print(" ");
  381. //serial_print("analogRead");
  382. //return 0;
  383. if (calibrating) wait_for_cal();
  384. //pin = 5; // PTD1/SE5b, pin 14, analog 0
  385. #if defined(__MK20DX256__)
  386. if (channel & 0x80) goto beginADC1;
  387. #endif
  388. __disable_irq();
  389. startADC0:
  390. //serial_print("startADC0\n");
  391. #if defined(__MKL26Z64__)
  392. if (channel & 0x40) {
  393. ADC0_CFG2 &= ~ADC_CFG2_MUXSEL;
  394. channel &= 0x3F;
  395. } else {
  396. ADC0_CFG2 |= ADC_CFG2_MUXSEL;
  397. }
  398. #endif
  399. ADC0_SC1A = channel;
  400. analogReadBusyADC0 = 1;
  401. __enable_irq();
  402. while (1) {
  403. __disable_irq();
  404. if ((ADC0_SC1A & ADC_SC1_COCO)) {
  405. result = ADC0_RA;
  406. analogReadBusyADC0 = 0;
  407. __enable_irq();
  408. result >>= analog_right_shift;
  409. return result;
  410. }
  411. // detect if analogRead was used from an interrupt
  412. // if so, our analogRead got canceled, so it must
  413. // be restarted.
  414. if (!analogReadBusyADC0) goto startADC0;
  415. __enable_irq();
  416. yield();
  417. }
  418. #if defined(__MK20DX256__)
  419. beginADC1:
  420. __disable_irq();
  421. startADC1:
  422. //serial_print("startADC0\n");
  423. // ADC1_CFG2[MUXSEL] bit selects between ADCx_SEn channels a and b.
  424. if (channel & 0x40) {
  425. ADC1_CFG2 &= ~ADC_CFG2_MUXSEL;
  426. } else {
  427. ADC1_CFG2 |= ADC_CFG2_MUXSEL;
  428. }
  429. ADC1_SC1A = channel & 0x3F;
  430. analogReadBusyADC1 = 1;
  431. __enable_irq();
  432. while (1) {
  433. __disable_irq();
  434. if ((ADC1_SC1A & ADC_SC1_COCO)) {
  435. result = ADC1_RA;
  436. analogReadBusyADC1 = 0;
  437. __enable_irq();
  438. result >>= analog_right_shift;
  439. return result;
  440. }
  441. // detect if analogRead was used from an interrupt
  442. // if so, our analogRead got canceled, so it must
  443. // be restarted.
  444. if (!analogReadBusyADC1) goto startADC1;
  445. __enable_irq();
  446. yield();
  447. }
  448. #endif
  449. }
  450. void analogWriteDAC0(int val)
  451. {
  452. #if defined(__MK20DX256__)
  453. SIM_SCGC2 |= SIM_SCGC2_DAC0;
  454. if (analog_reference_internal) {
  455. DAC0_C0 = DAC_C0_DACEN; // 1.2V ref is DACREF_1
  456. } else {
  457. DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS; // 3.3V VDDA is DACREF_2
  458. }
  459. if (val < 0) val = 0; // TODO: saturate instruction?
  460. else if (val > 4095) val = 4095;
  461. *(int16_t *)&(DAC0_DAT0L) = val;
  462. #elif defined(__MKL26Z64__)
  463. SIM_SCGC6 |= SIM_SCGC6_DAC0;
  464. if (analog_reference_internal == 0) {
  465. // use 3.3V VDDA power as the reference (this is the default)
  466. DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS | DAC_C0_DACSWTRG; // 3.3V VDDA
  467. } else {
  468. // use whatever voltage is on the AREF pin
  469. DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACSWTRG; // 3.3V VDDA
  470. }
  471. if (val < 0) val = 0;
  472. else if (val > 4095) val = 4095;
  473. *(int16_t *)&(DAC0_DAT0L) = val;
  474. #endif
  475. }
  476. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  477. void analogWriteDAC1(int val)
  478. {
  479. SIM_SCGC2 |= SIM_SCGC2_DAC1;
  480. if (analog_reference_internal) {
  481. DAC1_C0 = DAC_C0_DACEN; // 1.2V ref is DACREF_1
  482. } else {
  483. DAC1_C0 = DAC_C0_DACEN | DAC_C0_DACRFS; // 3.3V VDDA is DACREF_2
  484. }
  485. if (val < 0) val = 0; // TODO: saturate instruction?
  486. else if (val > 4095) val = 4095;
  487. *(int16_t *)&(DAC1_DAT0L) = val;
  488. }
  489. #endif