Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

214 lines
5.0KB

  1. #include "imxrt.h"
  2. #include "core_pins.h"
  3. #include "debug/printf.h"
  4. static uint8_t calibrating;
  5. static uint8_t analog_config_bits = 10;
  6. static uint8_t analog_num_average = 4;
  7. const uint8_t pin_to_channel[] = { // pg 482
  8. 7, // 0/A0 AD_B1_02
  9. 8, // 1/A1 AD_B1_03
  10. 12, // 2/A2 AD_B1_07
  11. 11, // 3/A3 AD_B1_06
  12. 6, // 4/A4 AD_B1_01
  13. 5, // 5/A5 AD_B1_00
  14. 15, // 6/A6 AD_B1_10
  15. 0, // 7/A7 AD_B1_11
  16. 13, // 8/A8 AD_B1_08
  17. 14, // 9/A9 AD_B1_09
  18. #if 0
  19. 128, // 10
  20. 128, // 11
  21. 128, // 12
  22. 128, // 13
  23. #else
  24. 1, // 24/A10 AD_B0_12
  25. 2, // 25/A11 AD_B0_13
  26. 128+3, // 26/A12 AD_B1_14 - only on ADC2, 3
  27. 128+4, // 27/A13 AD_B1_15 - only on ADC2, 4
  28. #endif
  29. 7, // 14/A0 AD_B1_02
  30. 8, // 15/A1 AD_B1_03
  31. 12, // 16/A2 AD_B1_07
  32. 11, // 17/A3 AD_B1_06
  33. 6, // 18/A4 AD_B1_01
  34. 5, // 19/A5 AD_B1_00
  35. 15, // 20/A6 AD_B1_10
  36. 0, // 21/A7 AD_B1_11
  37. 13, // 22/A8 AD_B1_08
  38. 14, // 23/A9 AD_B1_09
  39. 1, // 24/A10 AD_B0_12
  40. 2, // 25/A11 AD_B0_13
  41. 128+3, // 26/A12 AD_B1_14 - only on ADC2, 3
  42. 128+4 // 27/A13 AD_B1_15 - only on ADC2, 4
  43. };
  44. static void wait_for_cal(void)
  45. {
  46. //printf("wait_for_cal\n");
  47. while (ADC1_GC & ADC_GC_CAL) ;
  48. // TODO: check CALF, but what do to about CAL failure?
  49. calibrating = 0;
  50. //printf("cal complete\n");
  51. }
  52. int analogRead(uint8_t pin)
  53. {
  54. if (pin > sizeof(pin_to_channel)) return 0;
  55. if (calibrating) wait_for_cal();
  56. uint8_t ch = pin_to_channel[pin];
  57. // printf("%d\n", ch);
  58. // if (ch > 15) return 0;
  59. if(!(ch & 0x80)) {
  60. ADC1_HC0 = ch;
  61. while (!(ADC1_HS & ADC_HS_COCO0)) ; // wait
  62. return ADC1_R0;
  63. } else {
  64. ADC2_HC0 = ch & 0x7f;
  65. while (!(ADC2_HS & ADC_HS_COCO0)) ; // wait
  66. return ADC2_R0;
  67. }
  68. }
  69. void analogReference(uint8_t type)
  70. {
  71. }
  72. void analogReadRes(unsigned int bits)
  73. {
  74. uint32_t tmp32, mode;
  75. if (bits == 8) {
  76. // 8 bit conversion (17 clocks) plus 8 clocks for input settling
  77. mode = ADC_CFG_MODE(0) | ADC_CFG_ADSTS(3);
  78. } else if (bits == 10) {
  79. // 10 bit conversion (17 clocks) plus 20 clocks for input settling
  80. mode = ADC_CFG_MODE(1) | ADC_CFG_ADSTS(2) | ADC_CFG_ADLSMP;
  81. } else {
  82. // 12 bit conversion (25 clocks) plus 24 clocks for input settling
  83. mode = ADC_CFG_MODE(2) | ADC_CFG_ADSTS(3) | ADC_CFG_ADLSMP;
  84. }
  85. tmp32 = (ADC1_CFG & (0xFFFFFC00));
  86. tmp32 |= (ADC1_CFG & (0x03)); // ADICLK
  87. tmp32 |= (ADC1_CFG & (0xE0)); // ADIV & ADLPC
  88. tmp32 |= mode;
  89. ADC1_CFG = tmp32;
  90. tmp32 = (ADC2_CFG & (0xFFFFFC00));
  91. tmp32 |= (ADC2_CFG & (0x03)); // ADICLK
  92. tmp32 |= (ADC2_CFG & (0xE0)); // ADIV & ADLPC
  93. tmp32 |= mode;
  94. ADC2_CFG = tmp32;
  95. }
  96. void analogReadAveraging(unsigned int num)
  97. {
  98. uint32_t mode, mode1;
  99. //disable averaging, ADC1 and ADC2
  100. ADC1_GC &= ~0x20;
  101. mode = ADC1_CFG & ~0xC000;
  102. ADC2_GC &= ~0x20;
  103. mode1 = ADC2_CFG & ~0xC000;
  104. if (num >= 32) {
  105. mode |= ADC_CFG_AVGS(3);
  106. mode1 |= ADC_CFG_AVGS(3);
  107. } else if (num >= 16) {
  108. mode |= ADC_CFG_AVGS(2);
  109. mode1 |= ADC_CFG_AVGS(2);
  110. } else if (num >= 8) {
  111. mode |= ADC_CFG_AVGS(1);
  112. mode1 |= ADC_CFG_AVGS(1);
  113. } else if (num >= 4) {
  114. mode |= ADC_CFG_AVGS(0);
  115. mode1 |= ADC_CFG_AVGS(0);
  116. } else {
  117. mode |= 0;
  118. mode1 |= 0;
  119. }
  120. ADC1_CFG |= mode;
  121. ADC2_CFG |= mode1;
  122. if(num >= 4){
  123. ADC1_GC |= ADC_GC_AVGE;// turns on averaging
  124. ADC2_GC |= ADC_GC_AVGE;// turns on averaging
  125. }
  126. }
  127. #define MAX_ADC_CLOCK 20000000
  128. __attribute__((section(".progmem")))
  129. 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. }