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.

214 lines
5.0KB

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