fsl_adc16.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /*
  2. * Copyright (c) 2015, 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_adc16.h"
  31. /*******************************************************************************
  32. * Prototypes
  33. ******************************************************************************/
  34. /*!
  35. * @brief Get instance number for ADC16 module.
  36. *
  37. * @param base ADC16 peripheral base address
  38. */
  39. static uint32_t ADC16_GetInstance(ADC_Type *base);
  40. /*******************************************************************************
  41. * Variables
  42. ******************************************************************************/
  43. /*! @brief Pointers to ADC16 bases for each instance. */
  44. static ADC_Type *const s_adc16Bases[] = ADC_BASE_PTRS;
  45. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  46. /*! @brief Pointers to ADC16 clocks for each instance. */
  47. static const clock_ip_name_t s_adc16Clocks[] = ADC16_CLOCKS;
  48. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  49. /*******************************************************************************
  50. * Code
  51. ******************************************************************************/
  52. static uint32_t ADC16_GetInstance(ADC_Type *base)
  53. {
  54. uint32_t instance;
  55. /* Find the instance index from base address mappings. */
  56. for (instance = 0; instance < ARRAY_SIZE(s_adc16Bases); instance++)
  57. {
  58. if (s_adc16Bases[instance] == base)
  59. {
  60. break;
  61. }
  62. }
  63. assert(instance < ARRAY_SIZE(s_adc16Bases));
  64. return instance;
  65. }
  66. void ADC16_Init(ADC_Type *base, const adc16_config_t *config)
  67. {
  68. assert(NULL != config);
  69. uint32_t tmp32;
  70. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  71. /* Enable the clock. */
  72. CLOCK_EnableClock(s_adc16Clocks[ADC16_GetInstance(base)]);
  73. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  74. /* ADCx_CFG1. */
  75. tmp32 = ADC_CFG1_ADICLK(config->clockSource) | ADC_CFG1_MODE(config->resolution);
  76. if (kADC16_LongSampleDisabled != config->longSampleMode)
  77. {
  78. tmp32 |= ADC_CFG1_ADLSMP_MASK;
  79. }
  80. tmp32 |= ADC_CFG1_ADIV(config->clockDivider);
  81. if (config->enableLowPower)
  82. {
  83. tmp32 |= ADC_CFG1_ADLPC_MASK;
  84. }
  85. base->CFG1 = tmp32;
  86. /* ADCx_CFG2. */
  87. tmp32 = base->CFG2 & ~(ADC_CFG2_ADACKEN_MASK | ADC_CFG2_ADHSC_MASK | ADC_CFG2_ADLSTS_MASK);
  88. if (kADC16_LongSampleDisabled != config->longSampleMode)
  89. {
  90. tmp32 |= ADC_CFG2_ADLSTS(config->longSampleMode);
  91. }
  92. if (config->enableHighSpeed)
  93. {
  94. tmp32 |= ADC_CFG2_ADHSC_MASK;
  95. }
  96. if (config->enableAsynchronousClock)
  97. {
  98. tmp32 |= ADC_CFG2_ADACKEN_MASK;
  99. }
  100. base->CFG2 = tmp32;
  101. /* ADCx_SC2. */
  102. tmp32 = base->SC2 & ~(ADC_SC2_REFSEL_MASK);
  103. tmp32 |= ADC_SC2_REFSEL(config->referenceVoltageSource);
  104. base->SC2 = tmp32;
  105. /* ADCx_SC3. */
  106. if (config->enableContinuousConversion)
  107. {
  108. base->SC3 |= ADC_SC3_ADCO_MASK;
  109. }
  110. else
  111. {
  112. base->SC3 &= ~ADC_SC3_ADCO_MASK;
  113. }
  114. }
  115. void ADC16_Deinit(ADC_Type *base)
  116. {
  117. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  118. /* Disable the clock. */
  119. CLOCK_DisableClock(s_adc16Clocks[ADC16_GetInstance(base)]);
  120. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  121. }
  122. void ADC16_GetDefaultConfig(adc16_config_t *config)
  123. {
  124. assert(NULL != config);
  125. config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
  126. config->clockSource = kADC16_ClockSourceAsynchronousClock;
  127. config->enableAsynchronousClock = true;
  128. config->clockDivider = kADC16_ClockDivider8;
  129. config->resolution = kADC16_ResolutionSE12Bit;
  130. config->longSampleMode = kADC16_LongSampleDisabled;
  131. config->enableHighSpeed = false;
  132. config->enableLowPower = false;
  133. config->enableContinuousConversion = false;
  134. }
  135. #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
  136. status_t ADC16_DoAutoCalibration(ADC_Type *base)
  137. {
  138. bool bHWTrigger = false;
  139. volatile uint32_t tmp32; /* 'volatile' here is for the dummy read of ADCx_R[0] register. */
  140. status_t status = kStatus_Success;
  141. /* The calibration would be failed when in hardwar mode.
  142. * Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/
  143. if (0U != (ADC_SC2_ADTRG_MASK & base->SC2))
  144. {
  145. bHWTrigger = true;
  146. base->SC2 &= ~ADC_SC2_ADTRG_MASK;
  147. }
  148. /* Clear the CALF and launch the calibration. */
  149. base->SC3 |= ADC_SC3_CAL_MASK | ADC_SC3_CALF_MASK;
  150. while (0U == (kADC16_ChannelConversionDoneFlag & ADC16_GetChannelStatusFlags(base, 0U)))
  151. {
  152. /* Check the CALF when the calibration is active. */
  153. if (0U != (kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base)))
  154. {
  155. status = kStatus_Fail;
  156. break;
  157. }
  158. }
  159. tmp32 = base->R[0]; /* Dummy read to clear COCO caused by calibration. */
  160. /* Restore the hardware trigger setting if it was enabled before. */
  161. if (bHWTrigger)
  162. {
  163. base->SC2 |= ADC_SC2_ADTRG_MASK;
  164. }
  165. /* Check the CALF at the end of calibration. */
  166. if (0U != (kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base)))
  167. {
  168. status = kStatus_Fail;
  169. }
  170. if (kStatus_Success != status) /* Check if the calibration process is succeed. */
  171. {
  172. return status;
  173. }
  174. /* Calculate the calibration values. */
  175. tmp32 = base->CLP0 + base->CLP1 + base->CLP2 + base->CLP3 + base->CLP4 + base->CLPS;
  176. tmp32 = 0x8000U | (tmp32 >> 1U);
  177. base->PG = tmp32;
  178. #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
  179. tmp32 = base->CLM0 + base->CLM1 + base->CLM2 + base->CLM3 + base->CLM4 + base->CLMS;
  180. tmp32 = 0x8000U | (tmp32 >> 1U);
  181. base->MG = tmp32;
  182. #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
  183. return kStatus_Success;
  184. }
  185. #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
  186. #if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT
  187. void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode)
  188. {
  189. if (kADC16_ChannelMuxA == mode)
  190. {
  191. base->CFG2 &= ~ADC_CFG2_MUXSEL_MASK;
  192. }
  193. else /* kADC16_ChannelMuxB. */
  194. {
  195. base->CFG2 |= ADC_CFG2_MUXSEL_MASK;
  196. }
  197. }
  198. #endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */
  199. void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config)
  200. {
  201. uint32_t tmp32 = base->SC2 & ~(ADC_SC2_ACFE_MASK | ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK);
  202. if (!config) /* Pass "NULL" to disable the feature. */
  203. {
  204. base->SC2 = tmp32;
  205. return;
  206. }
  207. /* Enable the feature. */
  208. tmp32 |= ADC_SC2_ACFE_MASK;
  209. /* Select the hardware compare working mode. */
  210. switch (config->hardwareCompareMode)
  211. {
  212. case kADC16_HardwareCompareMode0:
  213. break;
  214. case kADC16_HardwareCompareMode1:
  215. tmp32 |= ADC_SC2_ACFGT_MASK;
  216. break;
  217. case kADC16_HardwareCompareMode2:
  218. tmp32 |= ADC_SC2_ACREN_MASK;
  219. break;
  220. case kADC16_HardwareCompareMode3:
  221. tmp32 |= ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK;
  222. break;
  223. default:
  224. break;
  225. }
  226. base->SC2 = tmp32;
  227. /* Load the compare values. */
  228. base->CV1 = ADC_CV1_CV(config->value1);
  229. base->CV2 = ADC_CV2_CV(config->value2);
  230. }
  231. #if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE
  232. void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode)
  233. {
  234. uint32_t tmp32 = base->SC3 & ~(ADC_SC3_AVGE_MASK | ADC_SC3_AVGS_MASK);
  235. if (kADC16_HardwareAverageDisabled != mode)
  236. {
  237. tmp32 |= ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(mode);
  238. }
  239. base->SC3 = tmp32;
  240. }
  241. #endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */
  242. #if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA
  243. void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config)
  244. {
  245. uint32_t tmp32;
  246. if (!config) /* Passing "NULL" is to disable the feature. */
  247. {
  248. base->PGA = 0U;
  249. return;
  250. }
  251. /* Enable the PGA and set the gain value. */
  252. tmp32 = ADC_PGA_PGAEN_MASK | ADC_PGA_PGAG(config->pgaGain);
  253. /* Configure the misc features for PGA. */
  254. if (config->enableRunInNormalMode)
  255. {
  256. tmp32 |= ADC_PGA_PGALPb_MASK;
  257. }
  258. #if defined(FSL_FEATURE_ADC16_HAS_PGA_CHOPPING) && FSL_FEATURE_ADC16_HAS_PGA_CHOPPING
  259. if (config->disablePgaChopping)
  260. {
  261. tmp32 |= ADC_PGA_PGACHPb_MASK;
  262. }
  263. #endif /* FSL_FEATURE_ADC16_HAS_PGA_CHOPPING */
  264. #if defined(FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT) && FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT
  265. if (config->enableRunInOffsetMeasurement)
  266. {
  267. tmp32 |= ADC_PGA_PGAOFSM_MASK;
  268. }
  269. #endif /* FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT */
  270. base->PGA = tmp32;
  271. }
  272. #endif /* FSL_FEATURE_ADC16_HAS_PGA */
  273. uint32_t ADC16_GetStatusFlags(ADC_Type *base)
  274. {
  275. uint32_t ret = 0;
  276. if (0U != (base->SC2 & ADC_SC2_ADACT_MASK))
  277. {
  278. ret |= kADC16_ActiveFlag;
  279. }
  280. #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
  281. if (0U != (base->SC3 & ADC_SC3_CALF_MASK))
  282. {
  283. ret |= kADC16_CalibrationFailedFlag;
  284. }
  285. #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
  286. return ret;
  287. }
  288. void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask)
  289. {
  290. #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
  291. if (0U != (mask & kADC16_CalibrationFailedFlag))
  292. {
  293. base->SC3 |= ADC_SC3_CALF_MASK;
  294. }
  295. #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
  296. }
  297. void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config)
  298. {
  299. assert(channelGroup < ADC_SC1_COUNT);
  300. assert(NULL != config);
  301. uint32_t sc1 = ADC_SC1_ADCH(config->channelNumber); /* Set the channel number. */
  302. #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
  303. /* Enable the differential conversion. */
  304. if (config->enableDifferentialConversion)
  305. {
  306. sc1 |= ADC_SC1_DIFF_MASK;
  307. }
  308. #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
  309. /* Enable the interrupt when the conversion is done. */
  310. if (config->enableInterruptOnConversionCompleted)
  311. {
  312. sc1 |= ADC_SC1_AIEN_MASK;
  313. }
  314. base->SC1[channelGroup] = sc1;
  315. }
  316. uint32_t ADC16_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup)
  317. {
  318. assert(channelGroup < ADC_SC1_COUNT);
  319. uint32_t ret = 0U;
  320. if (0U != (base->SC1[channelGroup] & ADC_SC1_COCO_MASK))
  321. {
  322. ret |= kADC16_ChannelConversionDoneFlag;
  323. }
  324. return ret;
  325. }