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.

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