fsl_adc.c 13 KB

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