fsl_adc.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /*
  2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "fsl_adc.h"
  31. #include "fsl_clock.h"
  32. static ADC_Type *const s_adcBases[] = ADC_BASE_PTRS;
  33. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  34. static const clock_ip_name_t s_adcClocks[] = ADC_CLOCKS;
  35. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  36. static uint32_t ADC_GetInstance(ADC_Type *base)
  37. {
  38. uint32_t instance;
  39. /* Find the instance index from base address mappings. */
  40. for (instance = 0; instance < ARRAY_SIZE(s_adcBases); instance++)
  41. {
  42. if (s_adcBases[instance] == base)
  43. {
  44. break;
  45. }
  46. }
  47. assert(instance < ARRAY_SIZE(s_adcBases));
  48. return instance;
  49. }
  50. void ADC_Init(ADC_Type *base, const adc_config_t *config)
  51. {
  52. assert(config != NULL);
  53. uint32_t tmp32 = 0U;
  54. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  55. /* Enable clock. */
  56. CLOCK_EnableClock(s_adcClocks[ADC_GetInstance(base)]);
  57. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  58. /* Disable the interrupts. */
  59. base->INTEN = 0U; /* Quickly disable all the interrupts. */
  60. /* Configure the ADC block. */
  61. tmp32 = ADC_CTRL_CLKDIV(config->clockDividerNumber);
  62. /* Async or Sync clock mode. */
  63. switch (config->clockMode)
  64. {
  65. case kADC_ClockAsynchronousMode:
  66. tmp32 |= ADC_CTRL_ASYNMODE_MASK;
  67. break;
  68. default: /* kADC_ClockSynchronousMode */
  69. break;
  70. }
  71. /* Resolution. */
  72. tmp32 |= ADC_CTRL_RESOL(config->resolution);
  73. /* Bypass calibration. */
  74. if (config->enableBypassCalibration)
  75. {
  76. tmp32 |= ADC_CTRL_BYPASSCAL_MASK;
  77. }
  78. /* Sample time clock count. */
  79. tmp32 |= ADC_CTRL_TSAMP(config->sampleTimeNumber);
  80. base->CTRL = tmp32;
  81. }
  82. void ADC_GetDefaultConfig(adc_config_t *config)
  83. {
  84. config->clockMode = kADC_ClockSynchronousMode;
  85. config->clockDividerNumber = 0U;
  86. config->resolution = kADC_Resolution12bit;
  87. config->enableBypassCalibration = false;
  88. config->sampleTimeNumber = 0U;
  89. }
  90. void ADC_Deinit(ADC_Type *base)
  91. {
  92. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  93. /* Disable the clock. */
  94. CLOCK_DisableClock(s_adcClocks[ADC_GetInstance(base)]);
  95. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  96. }
  97. bool ADC_DoSelfCalibration(ADC_Type *base)
  98. {
  99. uint32_t i;
  100. /* Enable the converter. */
  101. /* This bit acn only be set 1 by software. It is cleared automatically whenever the ADC is powered down.
  102. This bit should be set after at least 10 ms after the ADC is powered on. */
  103. base->STARTUP = ADC_STARTUP_ADC_ENA_MASK;
  104. for (i = 0U; i < 0x10; i++) /* Wait a few clocks to startup up. */
  105. {
  106. __ASM("NOP");
  107. }
  108. if (!(base->STARTUP & ADC_STARTUP_ADC_ENA_MASK))
  109. {
  110. return false; /* ADC is not powered up. */
  111. }
  112. /* If not in by-pass mode, do the calibration. */
  113. if ((ADC_CALIB_CALREQD_MASK == (base->CALIB & ADC_CALIB_CALREQD_MASK)) &&
  114. (0U == (base->CTRL & ADC_CTRL_BYPASSCAL_MASK)))
  115. {
  116. /* Calibration is needed, do it now. */
  117. base->CALIB = ADC_CALIB_CALIB_MASK;
  118. i = 0xF0000;
  119. while ((ADC_CALIB_CALIB_MASK == (base->CALIB & ADC_CALIB_CALIB_MASK)) && (--i))
  120. {
  121. }
  122. if (i == 0U)
  123. {
  124. return false; /* Calibration timeout. */
  125. }
  126. }
  127. /* A dummy conversion cycle will be performed. */
  128. base->STARTUP |= ADC_STARTUP_ADC_INIT_MASK;
  129. i = 0x7FFFF;
  130. while ((ADC_STARTUP_ADC_INIT_MASK == (base->STARTUP & ADC_STARTUP_ADC_INIT_MASK)) && (--i))
  131. {
  132. }
  133. if (i == 0U)
  134. {
  135. return false;
  136. }
  137. return true;
  138. }
  139. void ADC_SetConvSeqAConfig(ADC_Type *base, const adc_conv_seq_config_t *config)
  140. {
  141. assert(config != NULL);
  142. uint32_t tmp32;
  143. tmp32 = ADC_SEQ_CTRL_CHANNELS(config->channelMask) /* Channel mask. */
  144. | ADC_SEQ_CTRL_TRIGGER(config->triggerMask); /* Trigger mask. */
  145. /* Polarity for tirgger signal. */
  146. switch (config->triggerPolarity)
  147. {
  148. case kADC_TriggerPolarityPositiveEdge:
  149. tmp32 |= ADC_SEQ_CTRL_TRIGPOL_MASK;
  150. break;
  151. default: /* kADC_TriggerPolarityNegativeEdge */
  152. break;
  153. }
  154. /* Bypass the clock Sync. */
  155. if (config->enableSyncBypass)
  156. {
  157. tmp32 |= ADC_SEQ_CTRL_SYNCBYPASS_MASK;
  158. }
  159. /* Interrupt point. */
  160. switch (config->interruptMode)
  161. {
  162. case kADC_InterruptForEachSequence:
  163. tmp32 |= ADC_SEQ_CTRL_MODE_MASK;
  164. break;
  165. default: /* kADC_InterruptForEachConversion */
  166. break;
  167. }
  168. /* One trigger for a conversion, or for a sequence. */
  169. if (config->enableSingleStep)
  170. {
  171. tmp32 |= ADC_SEQ_CTRL_SINGLESTEP_MASK;
  172. }
  173. base->SEQ_CTRL[0] = tmp32;
  174. }
  175. void ADC_SetConvSeqBConfig(ADC_Type *base, const adc_conv_seq_config_t *config)
  176. {
  177. assert(config != NULL);
  178. uint32_t tmp32;
  179. tmp32 = ADC_SEQ_CTRL_CHANNELS(config->channelMask) /* Channel mask. */
  180. | ADC_SEQ_CTRL_TRIGGER(config->triggerMask); /* Trigger mask. */
  181. /* Polarity for tirgger signal. */
  182. switch (config->triggerPolarity)
  183. {
  184. case kADC_TriggerPolarityPositiveEdge:
  185. tmp32 |= ADC_SEQ_CTRL_TRIGPOL_MASK;
  186. break;
  187. default: /* kADC_TriggerPolarityPositiveEdge */
  188. break;
  189. }
  190. /* Bypass the clock Sync. */
  191. if (config->enableSyncBypass)
  192. {
  193. tmp32 |= ADC_SEQ_CTRL_SYNCBYPASS_MASK;
  194. }
  195. /* Interrupt point. */
  196. switch (config->interruptMode)
  197. {
  198. case kADC_InterruptForEachSequence:
  199. tmp32 |= ADC_SEQ_CTRL_MODE_MASK;
  200. break;
  201. default: /* kADC_InterruptForEachConversion */
  202. break;
  203. }
  204. /* One trigger for a conversion, or for a sequence. */
  205. if (config->enableSingleStep)
  206. {
  207. tmp32 |= ADC_SEQ_CTRL_SINGLESTEP_MASK;
  208. }
  209. base->SEQ_CTRL[1] = tmp32;
  210. }
  211. bool ADC_GetConvSeqAGlobalConversionResult(ADC_Type *base, adc_result_info_t *info)
  212. {
  213. assert(info != NULL);
  214. uint32_t tmp32 = base->SEQ_GDAT[0]; /* Read to clear the status. */
  215. if (0U == (ADC_SEQ_GDAT_DATAVALID_MASK & tmp32))
  216. {
  217. return false;
  218. }
  219. info->result = (tmp32 & ADC_SEQ_GDAT_RESULT_MASK) >> ADC_SEQ_GDAT_RESULT_SHIFT;
  220. info->thresholdCompareStatus =
  221. (adc_threshold_compare_status_t)((tmp32 & ADC_SEQ_GDAT_THCMPRANGE_MASK) >> ADC_SEQ_GDAT_THCMPRANGE_SHIFT);
  222. info->thresholdCorssingStatus =
  223. (adc_threshold_crossing_status_t)((tmp32 & ADC_SEQ_GDAT_THCMPCROSS_MASK) >> ADC_SEQ_GDAT_THCMPCROSS_SHIFT);
  224. info->channelNumber = (tmp32 & ADC_SEQ_GDAT_CHN_MASK) >> ADC_SEQ_GDAT_CHN_SHIFT;
  225. info->overrunFlag = ((tmp32 & ADC_SEQ_GDAT_OVERRUN_MASK) == ADC_SEQ_GDAT_OVERRUN_MASK);
  226. return true;
  227. }
  228. bool ADC_GetConvSeqBGlobalConversionResult(ADC_Type *base, adc_result_info_t *info)
  229. {
  230. assert(info != NULL);
  231. uint32_t tmp32 = base->SEQ_GDAT[1]; /* Read to clear the status. */
  232. if (0U == (ADC_SEQ_GDAT_DATAVALID_MASK & tmp32))
  233. {
  234. return false;
  235. }
  236. info->result = (tmp32 & ADC_SEQ_GDAT_RESULT_MASK) >> ADC_SEQ_GDAT_RESULT_SHIFT;
  237. info->thresholdCompareStatus =
  238. (adc_threshold_compare_status_t)((tmp32 & ADC_SEQ_GDAT_THCMPRANGE_MASK) >> ADC_SEQ_GDAT_THCMPRANGE_SHIFT);
  239. info->thresholdCorssingStatus =
  240. (adc_threshold_crossing_status_t)((tmp32 & ADC_SEQ_GDAT_THCMPCROSS_MASK) >> ADC_SEQ_GDAT_THCMPCROSS_SHIFT);
  241. info->channelNumber = (tmp32 & ADC_SEQ_GDAT_CHN_MASK) >> ADC_SEQ_GDAT_CHN_SHIFT;
  242. info->overrunFlag = ((tmp32 & ADC_SEQ_GDAT_OVERRUN_MASK) == ADC_SEQ_GDAT_OVERRUN_MASK);
  243. return true;
  244. }
  245. bool ADC_GetChannelConversionResult(ADC_Type *base, uint32_t channel, adc_result_info_t *info)
  246. {
  247. assert(info != NULL);
  248. assert(channel < ADC_DAT_COUNT);
  249. uint32_t tmp32 = base->DAT[channel]; /* Read to clear the status. */
  250. if (0U == (ADC_DAT_DATAVALID_MASK & tmp32))
  251. {
  252. return false;
  253. }
  254. info->result = (tmp32 & ADC_DAT_RESULT_MASK) >> ADC_DAT_RESULT_SHIFT;
  255. info->thresholdCompareStatus =
  256. (adc_threshold_compare_status_t)((tmp32 & ADC_DAT_THCMPRANGE_MASK) >> ADC_DAT_THCMPRANGE_SHIFT);
  257. info->thresholdCorssingStatus =
  258. (adc_threshold_crossing_status_t)((tmp32 & ADC_DAT_THCMPCROSS_MASK) >> ADC_DAT_THCMPCROSS_SHIFT);
  259. info->channelNumber = (tmp32 & ADC_DAT_CHANNEL_MASK) >> ADC_DAT_CHANNEL_SHIFT;
  260. info->overrunFlag = ((tmp32 & ADC_DAT_OVERRUN_MASK) == ADC_DAT_OVERRUN_MASK);
  261. return true;
  262. }