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 5.3KB

4 yıl önce
4 yıl önce
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include "imxrt.h"
  2. #include "core_pins.h"
  3. #include "debug/printf.h"
  4. #include "avr/pgmspace.h"
  5. static uint8_t calibrating;
  6. static uint8_t analog_config_bits = 10;
  7. static uint8_t analog_num_average = 4;
  8. const uint8_t pin_to_channel[] = { // pg 482
  9. 7, // 0/A0 AD_B1_02
  10. 8, // 1/A1 AD_B1_03
  11. 12, // 2/A2 AD_B1_07
  12. 11, // 3/A3 AD_B1_06
  13. 6, // 4/A4 AD_B1_01
  14. 5, // 5/A5 AD_B1_00
  15. 15, // 6/A6 AD_B1_10
  16. 0, // 7/A7 AD_B1_11
  17. 13, // 8/A8 AD_B1_08
  18. 14, // 9/A9 AD_B1_09
  19. 1, // 24/A10 AD_B0_12
  20. 2, // 25/A11 AD_B0_13
  21. 128+3, // 26/A12 AD_B1_14 - only on ADC2, 3
  22. 128+4, // 27/A13 AD_B1_15 - only on ADC2, 4
  23. 7, // 14/A0 AD_B1_02
  24. 8, // 15/A1 AD_B1_03
  25. 12, // 16/A2 AD_B1_07
  26. 11, // 17/A3 AD_B1_06
  27. 6, // 18/A4 AD_B1_01
  28. 5, // 19/A5 AD_B1_00
  29. 15, // 20/A6 AD_B1_10
  30. 0, // 21/A7 AD_B1_11
  31. 13, // 22/A8 AD_B1_08
  32. 14, // 23/A9 AD_B1_09
  33. 1, // 24/A10 AD_B0_12
  34. 2, // 25/A11 AD_B0_13
  35. 128+3, // 26/A12 AD_B1_14 - only on ADC2, 3
  36. 128+4, // 27/A13 AD_B1_15 - only on ADC2, 4
  37. #ifdef ARDUINO_TEENSY41
  38. 255, // 28
  39. 255, // 29
  40. 255, // 30
  41. 255, // 31
  42. 255, // 32
  43. 255, // 33
  44. 255, // 34
  45. 255, // 35
  46. 255, // 36
  47. 255, // 37
  48. 128+1, // 38/A14 AD_B1_12 - only on ADC2, 1
  49. 128+2, // 39/A15 AD_B1_13 - only on ADC2, 2
  50. 9, // 40/A16 AD_B1_04
  51. 10, // 41/A17 AD_B1_05
  52. #endif
  53. };
  54. static void wait_for_cal(void)
  55. {
  56. //printf("wait_for_cal\n");
  57. while (ADC1_GC & ADC_GC_CAL) ;
  58. while (ADC2_GC & ADC_GC_CAL) ;
  59. // TODO: check CALF, but what do to about CAL failure?
  60. calibrating = 0;
  61. //printf("cal complete\n");
  62. }
  63. int analogRead(uint8_t pin)
  64. {
  65. if (pin > sizeof(pin_to_channel)) return 0;
  66. if (calibrating) wait_for_cal();
  67. uint8_t ch = pin_to_channel[pin];
  68. if (ch == 255) return 0;
  69. // printf("%d\n", ch);
  70. // if (ch > 15) return 0;
  71. if(!(ch & 0x80)) {
  72. ADC1_HC0 = ch;
  73. while (!(ADC1_HS & ADC_HS_COCO0)) ; // wait
  74. return ADC1_R0;
  75. } else {
  76. ADC2_HC0 = ch & 0x7f;
  77. while (!(ADC2_HS & ADC_HS_COCO0)) ; // wait
  78. return ADC2_R0;
  79. }
  80. }
  81. void analogReference(uint8_t type)
  82. {
  83. }
  84. void analogReadRes(unsigned int bits)
  85. {
  86. uint32_t tmp32, mode;
  87. if (bits == 8) {
  88. // 8 bit conversion (17 clocks) plus 8 clocks for input settling
  89. mode = ADC_CFG_MODE(0) | ADC_CFG_ADSTS(3);
  90. } else if (bits == 10) {
  91. // 10 bit conversion (17 clocks) plus 20 clocks for input settling
  92. mode = ADC_CFG_MODE(1) | ADC_CFG_ADSTS(2) | ADC_CFG_ADLSMP;
  93. } else {
  94. // 12 bit conversion (25 clocks) plus 24 clocks for input settling
  95. mode = ADC_CFG_MODE(2) | ADC_CFG_ADSTS(3) | ADC_CFG_ADLSMP;
  96. }
  97. tmp32 = (ADC1_CFG & (0xFFFFFC00));
  98. tmp32 |= (ADC1_CFG & (0x03)); // ADICLK
  99. tmp32 |= (ADC1_CFG & (0xE0)); // ADIV & ADLPC
  100. tmp32 |= mode;
  101. ADC1_CFG = tmp32;
  102. tmp32 = (ADC2_CFG & (0xFFFFFC00));
  103. tmp32 |= (ADC2_CFG & (0x03)); // ADICLK
  104. tmp32 |= (ADC2_CFG & (0xE0)); // ADIV & ADLPC
  105. tmp32 |= mode;
  106. ADC2_CFG = tmp32;
  107. }
  108. void analogReadAveraging(unsigned int num)
  109. {
  110. uint32_t mode, mode1;
  111. //disable averaging, ADC1 and ADC2
  112. ADC1_GC &= ~0x20;
  113. mode = ADC1_CFG & ~0xC000;
  114. ADC2_GC &= ~0x20;
  115. mode1 = ADC2_CFG & ~0xC000;
  116. if (num >= 32) {
  117. mode |= ADC_CFG_AVGS(3);
  118. mode1 |= ADC_CFG_AVGS(3);
  119. } else if (num >= 16) {
  120. mode |= ADC_CFG_AVGS(2);
  121. mode1 |= ADC_CFG_AVGS(2);
  122. } else if (num >= 8) {
  123. mode |= ADC_CFG_AVGS(1);
  124. mode1 |= ADC_CFG_AVGS(1);
  125. } else if (num >= 4) {
  126. mode |= ADC_CFG_AVGS(0);
  127. mode1 |= ADC_CFG_AVGS(0);
  128. } else {
  129. mode |= 0;
  130. mode1 |= 0;
  131. }
  132. ADC1_CFG = mode;
  133. ADC2_CFG = mode1;
  134. if(num >= 4){
  135. ADC1_GC |= ADC_GC_AVGE;// turns on averaging
  136. ADC2_GC |= ADC_GC_AVGE;// turns on averaging
  137. }
  138. }
  139. #define MAX_ADC_CLOCK 20000000
  140. FLASHMEM void analog_init(void)
  141. {
  142. uint32_t mode, avg=0;
  143. printf("analogInit\n");
  144. CCM_CCGR1 |= CCM_CCGR1_ADC1(CCM_CCGR_ON);
  145. CCM_CCGR1 |= CCM_CCGR1_ADC2(CCM_CCGR_ON);
  146. if (analog_config_bits == 8) {
  147. // 8 bit conversion (17 clocks) plus 8 clocks for input settling
  148. mode = ADC_CFG_MODE(0) | ADC_CFG_ADSTS(3);
  149. } else if (analog_config_bits == 10) {
  150. // 10 bit conversion (17 clocks) plus 20 clocks for input settling
  151. mode = ADC_CFG_MODE(1) | ADC_CFG_ADSTS(2) | ADC_CFG_ADLSMP;
  152. } else {
  153. // 12 bit conversion (25 clocks) plus 24 clocks for input settling
  154. mode = ADC_CFG_MODE(2) | ADC_CFG_ADSTS(3) | ADC_CFG_ADLSMP;
  155. }
  156. if (analog_num_average >= 4) {
  157. if (analog_num_average >= 32) {
  158. mode |= ADC_CFG_AVGS(3);
  159. } else if (analog_num_average >= 16) {
  160. mode |= ADC_CFG_AVGS(2);
  161. } else if (analog_num_average >= 8) {
  162. mode |= ADC_CFG_AVGS(1);
  163. }
  164. avg = ADC_GC_AVGE;
  165. }
  166. #if 1
  167. mode |= ADC_CFG_ADIV(1) | ADC_CFG_ADICLK(3); // async clock
  168. #else
  169. uint32_t clock = F_BUS;
  170. if (clock > MAX_ADC_CLOCK*8) {
  171. mode |= ADC_CFG_ADIV(3) | ADC_CFG_ADICLK(1); // use IPG/16
  172. } else if (clock > MAX_ADC_CLOCK*4) {
  173. mode |= ADC_CFG_ADIV(2) | ADC_CFG_ADICLK(1); // use IPG/8
  174. } else if (clock > MAX_ADC_CLOCK*2) {
  175. mode |= ADC_CFG_ADIV(1) | ADC_CFG_ADICLK(1); // use IPG/4
  176. } else if (clock > MAX_ADC_CLOCK) {
  177. mode |= ADC_CFG_ADIV(0) | ADC_CFG_ADICLK(1); // use IPG/2
  178. } else {
  179. mode |= ADC_CFG_ADIV(0) | ADC_CFG_ADICLK(0); // use IPG
  180. }
  181. #endif
  182. //ADC1
  183. ADC1_CFG = mode | ADC_CFG_ADHSC;
  184. ADC1_GC = avg | ADC_GC_CAL; // begin cal
  185. calibrating = 1;
  186. while (ADC1_GC & ADC_GC_CAL) ;
  187. calibrating = 0;
  188. //ADC2
  189. ADC2_CFG = mode | ADC_CFG_ADHSC;
  190. ADC2_GC = avg | ADC_GC_CAL; // begin cal
  191. calibrating = 1;
  192. while (ADC2_GC & ADC_GC_CAL) ;
  193. calibrating = 0;
  194. }