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.0KB

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