Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

495 Zeilen
16 KiB

  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2019 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_adc16.h"
  9. /* Component ID definition, used by tools. */
  10. #ifndef FSL_COMPONENT_ID
  11. #define FSL_COMPONENT_ID "platform.drivers.adc16"
  12. #endif
  13. /*******************************************************************************
  14. * Prototypes
  15. ******************************************************************************/
  16. /*!
  17. * @brief Get instance number for ADC16 module.
  18. *
  19. * @param base ADC16 peripheral base address
  20. */
  21. static uint32_t ADC16_GetInstance(ADC_Type *base);
  22. /*******************************************************************************
  23. * Variables
  24. ******************************************************************************/
  25. /*! @brief Pointers to ADC16 bases for each instance. */
  26. static ADC_Type *const s_adc16Bases[] = ADC_BASE_PTRS;
  27. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  28. /*! @brief Pointers to ADC16 clocks for each instance. */
  29. static const clock_ip_name_t s_adc16Clocks[] = ADC16_CLOCKS;
  30. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  31. /*******************************************************************************
  32. * Code
  33. ******************************************************************************/
  34. static uint32_t ADC16_GetInstance(ADC_Type *base)
  35. {
  36. uint32_t instance;
  37. /* Find the instance index from base address mappings. */
  38. for (instance = 0; instance < ARRAY_SIZE(s_adc16Bases); instance++)
  39. {
  40. if (s_adc16Bases[instance] == base)
  41. {
  42. break;
  43. }
  44. }
  45. assert(instance < ARRAY_SIZE(s_adc16Bases));
  46. return instance;
  47. }
  48. /*!
  49. * brief Initializes the ADC16 module.
  50. *
  51. * param base ADC16 peripheral base address.
  52. * param config Pointer to configuration structure. See "adc16_config_t".
  53. */
  54. void ADC16_Init(ADC_Type *base, const adc16_config_t *config)
  55. {
  56. assert(NULL != config);
  57. uint32_t tmp32;
  58. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  59. /* Enable the clock. */
  60. CLOCK_EnableClock(s_adc16Clocks[ADC16_GetInstance(base)]);
  61. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  62. /* ADCx_CFG1. */
  63. tmp32 = ADC_CFG1_ADICLK(config->clockSource) | ADC_CFG1_MODE(config->resolution);
  64. if (kADC16_LongSampleDisabled != config->longSampleMode)
  65. {
  66. tmp32 |= ADC_CFG1_ADLSMP_MASK;
  67. }
  68. tmp32 |= ADC_CFG1_ADIV(config->clockDivider);
  69. if (true == config->enableLowPower)
  70. {
  71. tmp32 |= ADC_CFG1_ADLPC_MASK;
  72. }
  73. base->CFG1 = tmp32;
  74. /* ADCx_CFG2. */
  75. tmp32 = base->CFG2 & ~(ADC_CFG2_ADACKEN_MASK | ADC_CFG2_ADHSC_MASK | ADC_CFG2_ADLSTS_MASK);
  76. if (kADC16_LongSampleDisabled != config->longSampleMode)
  77. {
  78. tmp32 |= ADC_CFG2_ADLSTS(config->longSampleMode);
  79. }
  80. if (true == config->enableHighSpeed)
  81. {
  82. tmp32 |= ADC_CFG2_ADHSC_MASK;
  83. }
  84. if (true == config->enableAsynchronousClock)
  85. {
  86. tmp32 |= ADC_CFG2_ADACKEN_MASK;
  87. }
  88. base->CFG2 = tmp32;
  89. /* ADCx_SC2. */
  90. tmp32 = base->SC2 & ~(ADC_SC2_REFSEL_MASK);
  91. tmp32 |= ADC_SC2_REFSEL(config->referenceVoltageSource);
  92. base->SC2 = tmp32;
  93. /* ADCx_SC3. */
  94. if (true == config->enableContinuousConversion)
  95. {
  96. base->SC3 |= ADC_SC3_ADCO_MASK;
  97. }
  98. else
  99. {
  100. base->SC3 &= ~ADC_SC3_ADCO_MASK;
  101. }
  102. }
  103. /*!
  104. * brief De-initializes the ADC16 module.
  105. *
  106. * param base ADC16 peripheral base address.
  107. */
  108. void ADC16_Deinit(ADC_Type *base)
  109. {
  110. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  111. /* Disable the clock. */
  112. CLOCK_DisableClock(s_adc16Clocks[ADC16_GetInstance(base)]);
  113. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  114. }
  115. /*!
  116. * brief Gets an available pre-defined settings for the converter's configuration.
  117. *
  118. * This function initializes the converter configuration structure with available settings. The default values are as
  119. * follows.
  120. * code
  121. * config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
  122. * config->clockSource = kADC16_ClockSourceAsynchronousClock;
  123. * config->enableAsynchronousClock = true;
  124. * config->clockDivider = kADC16_ClockDivider8;
  125. * config->resolution = kADC16_ResolutionSE12Bit;
  126. * config->longSampleMode = kADC16_LongSampleDisabled;
  127. * config->enableHighSpeed = false;
  128. * config->enableLowPower = false;
  129. * config->enableContinuousConversion = false;
  130. * endcode
  131. * param config Pointer to the configuration structure.
  132. */
  133. void ADC16_GetDefaultConfig(adc16_config_t *config)
  134. {
  135. assert(NULL != config);
  136. /* Initializes the configure structure to zero. */
  137. (void)memset(config, 0, sizeof(*config));
  138. config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
  139. config->clockSource = kADC16_ClockSourceAsynchronousClock;
  140. config->enableAsynchronousClock = true;
  141. config->clockDivider = kADC16_ClockDivider8;
  142. config->resolution = kADC16_ResolutionSE12Bit;
  143. config->longSampleMode = kADC16_LongSampleDisabled;
  144. config->enableHighSpeed = false;
  145. config->enableLowPower = false;
  146. config->enableContinuousConversion = false;
  147. }
  148. #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
  149. /*!
  150. * brief Automates the hardware calibration.
  151. *
  152. * This auto calibration helps to adjust the plus/minus side gain automatically.
  153. * Execute the calibration before using the converter. Note that the hardware trigger should be used
  154. * during the calibration.
  155. *
  156. * param base ADC16 peripheral base address.
  157. *
  158. * return Execution status.
  159. * retval kStatus_Success Calibration is done successfully.
  160. * retval kStatus_Fail Calibration has failed.
  161. */
  162. status_t ADC16_DoAutoCalibration(ADC_Type *base)
  163. {
  164. bool bHWTrigger = false;
  165. uint32_t tmp32;
  166. status_t status = kStatus_Success;
  167. /* The calibration would be failed when in hardwar mode.
  168. * Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/
  169. if (0U != (ADC_SC2_ADTRG_MASK & base->SC2))
  170. {
  171. bHWTrigger = true;
  172. base->SC2 &= ~ADC_SC2_ADTRG_MASK;
  173. }
  174. /* Clear the CALF and launch the calibration. */
  175. base->SC3 |= ADC_SC3_CAL_MASK | ADC_SC3_CALF_MASK;
  176. while (0U == ((uint32_t)kADC16_ChannelConversionDoneFlag & ADC16_GetChannelStatusFlags(base, 0U)))
  177. {
  178. /* Check the CALF when the calibration is active. */
  179. if (0U != ((uint32_t)kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base)))
  180. {
  181. status = kStatus_Fail;
  182. break;
  183. }
  184. }
  185. (void)base->R[0]; /* Dummy read to clear COCO caused by calibration. */
  186. /* Restore the hardware trigger setting if it was enabled before. */
  187. if (bHWTrigger)
  188. {
  189. base->SC2 |= ADC_SC2_ADTRG_MASK;
  190. }
  191. /* Check the CALF at the end of calibration. */
  192. if (0U != ((uint32_t)kADC16_CalibrationFailedFlag & ADC16_GetStatusFlags(base)))
  193. {
  194. status = kStatus_Fail;
  195. }
  196. if (kStatus_Success != status) /* Check if the calibration process is succeed. */
  197. {
  198. return status;
  199. }
  200. /* Calculate the calibration values. */
  201. tmp32 = base->CLP0;
  202. tmp32 += base->CLP1;
  203. tmp32 += base->CLP2;
  204. tmp32 += base->CLP3;
  205. tmp32 += base->CLP4;
  206. tmp32 += base->CLPS;
  207. tmp32 = 0x8000U | (tmp32 >> 1U);
  208. base->PG = tmp32;
  209. #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
  210. tmp32 = base->CLM0;
  211. tmp32 += base->CLM1;
  212. tmp32 += base->CLM2;
  213. tmp32 += base->CLM3;
  214. tmp32 += base->CLM4;
  215. tmp32 += base->CLMS;
  216. tmp32 = 0x8000U | (tmp32 >> 1U);
  217. base->MG = tmp32;
  218. #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
  219. return kStatus_Success;
  220. }
  221. #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
  222. #if defined(FSL_FEATURE_ADC16_HAS_MUX_SELECT) && FSL_FEATURE_ADC16_HAS_MUX_SELECT
  223. /*!
  224. * brief Sets the channel mux mode.
  225. *
  226. * Some sample pins share the same channel index. The channel mux mode decides which pin is used for an
  227. * indicated channel.
  228. *
  229. * param base ADC16 peripheral base address.
  230. * param mode Setting channel mux mode. See "adc16_channel_mux_mode_t".
  231. */
  232. void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode)
  233. {
  234. if (kADC16_ChannelMuxA == mode)
  235. {
  236. base->CFG2 &= ~ADC_CFG2_MUXSEL_MASK;
  237. }
  238. else /* kADC16_ChannelMuxB. */
  239. {
  240. base->CFG2 |= ADC_CFG2_MUXSEL_MASK;
  241. }
  242. }
  243. #endif /* FSL_FEATURE_ADC16_HAS_MUX_SELECT */
  244. /*!
  245. * brief Configures the hardware compare mode.
  246. *
  247. * The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the
  248. * result
  249. * in the compare range is available. To compare the range, see "adc16_hardware_compare_mode_t" or the appopriate
  250. * reference
  251. * manual for more information.
  252. *
  253. * param base ADC16 peripheral base address.
  254. * param config Pointer to the "adc16_hardware_compare_config_t" structure. Passing "NULL" disables the feature.
  255. */
  256. void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config)
  257. {
  258. uint32_t tmp32 = base->SC2 & ~(ADC_SC2_ACFE_MASK | ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK);
  259. if (NULL == config) /* Pass "NULL" to disable the feature. */
  260. {
  261. base->SC2 = tmp32;
  262. return;
  263. }
  264. /* Enable the feature. */
  265. tmp32 |= ADC_SC2_ACFE_MASK;
  266. /* Select the hardware compare working mode. */
  267. switch (config->hardwareCompareMode)
  268. {
  269. case kADC16_HardwareCompareMode0:
  270. break;
  271. case kADC16_HardwareCompareMode1:
  272. tmp32 |= ADC_SC2_ACFGT_MASK;
  273. break;
  274. case kADC16_HardwareCompareMode2:
  275. tmp32 |= ADC_SC2_ACREN_MASK;
  276. break;
  277. case kADC16_HardwareCompareMode3:
  278. tmp32 |= ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK;
  279. break;
  280. default:
  281. assert(false);
  282. break;
  283. }
  284. base->SC2 = tmp32;
  285. /* Load the compare values. */
  286. base->CV1 = ADC_CV1_CV(config->value1);
  287. base->CV2 = ADC_CV2_CV(config->value2);
  288. }
  289. #if defined(FSL_FEATURE_ADC16_HAS_HW_AVERAGE) && FSL_FEATURE_ADC16_HAS_HW_AVERAGE
  290. /*!
  291. * brief Sets the hardware average mode.
  292. *
  293. * The hardware average mode provides a way to process the conversion result automatically by using hardware. The
  294. * multiple
  295. * conversion results are accumulated and averaged internally making them easier to read.
  296. *
  297. * param base ADC16 peripheral base address.
  298. * param mode Setting the hardware average mode. See "adc16_hardware_average_mode_t".
  299. */
  300. void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode)
  301. {
  302. uint32_t tmp32 = base->SC3 & ~(ADC_SC3_AVGE_MASK | ADC_SC3_AVGS_MASK);
  303. if (kADC16_HardwareAverageDisabled != mode)
  304. {
  305. tmp32 |= ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(mode);
  306. }
  307. base->SC3 = tmp32;
  308. }
  309. #endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */
  310. #if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA
  311. /*!
  312. * brief Configures the PGA for the converter's front end.
  313. *
  314. * param base ADC16 peripheral base address.
  315. * param config Pointer to the "adc16_pga_config_t" structure. Passing "NULL" disables the feature.
  316. */
  317. void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config)
  318. {
  319. uint32_t tmp32;
  320. if (!config) /* Passing "NULL" is to disable the feature. */
  321. {
  322. base->PGA = 0U;
  323. return;
  324. }
  325. /* Enable the PGA and set the gain value. */
  326. tmp32 = ADC_PGA_PGAEN_MASK | ADC_PGA_PGAG(config->pgaGain);
  327. /* Configure the misc features for PGA. */
  328. if (config->enableRunInNormalMode)
  329. {
  330. tmp32 |= ADC_PGA_PGALPb_MASK;
  331. }
  332. #if defined(FSL_FEATURE_ADC16_HAS_PGA_CHOPPING) && FSL_FEATURE_ADC16_HAS_PGA_CHOPPING
  333. if (config->disablePgaChopping)
  334. {
  335. tmp32 |= ADC_PGA_PGACHPb_MASK;
  336. }
  337. #endif /* FSL_FEATURE_ADC16_HAS_PGA_CHOPPING */
  338. #if defined(FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT) && FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT
  339. if (config->enableRunInOffsetMeasurement)
  340. {
  341. tmp32 |= ADC_PGA_PGAOFSM_MASK;
  342. }
  343. #endif /* FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT */
  344. base->PGA = tmp32;
  345. }
  346. #endif /* FSL_FEATURE_ADC16_HAS_PGA */
  347. /*!
  348. * brief Gets the status flags of the converter.
  349. *
  350. * param base ADC16 peripheral base address.
  351. *
  352. * return Flags' mask if indicated flags are asserted. See "_adc16_status_flags".
  353. */
  354. uint32_t ADC16_GetStatusFlags(ADC_Type *base)
  355. {
  356. uint32_t ret = 0;
  357. if (0U != (base->SC2 & ADC_SC2_ADACT_MASK))
  358. {
  359. ret |= (uint32_t)kADC16_ActiveFlag;
  360. }
  361. #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
  362. if (0U != (base->SC3 & ADC_SC3_CALF_MASK))
  363. {
  364. ret |= (uint32_t)kADC16_CalibrationFailedFlag;
  365. }
  366. #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
  367. return ret;
  368. }
  369. /*!
  370. * brief Clears the status flags of the converter.
  371. *
  372. * param base ADC16 peripheral base address.
  373. * param mask Mask value for the cleared flags. See "_adc16_status_flags".
  374. */
  375. void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask)
  376. {
  377. #if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
  378. if (0U != (mask & (uint32_t)kADC16_CalibrationFailedFlag))
  379. {
  380. base->SC3 |= ADC_SC3_CALF_MASK;
  381. }
  382. #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
  383. }
  384. /*!
  385. * brief Configures the conversion channel.
  386. *
  387. * This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API
  388. * configures the channel while the external trigger source helps to trigger the conversion.
  389. *
  390. * Note that the "Channel Group" has a detailed description.
  391. * To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one
  392. * group of status and control registers, one for each conversion. The channel group parameter indicates which group of
  393. * registers are used, for example, channel group 0 is for Group A registers and channel group 1 is for Group B
  394. * registers. The
  395. * channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of
  396. * the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and
  397. * hardware
  398. * trigger modes. Channel group 1 and greater indicates multiple channel group registers for
  399. * use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual for
  400. * the
  401. * number of SC1n registers (channel groups) specific to this device. Channel group 1 or greater are not used
  402. * for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion.
  403. * Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and
  404. * vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a
  405. * conversion aborts the current conversion.
  406. *
  407. * param base ADC16 peripheral base address.
  408. * param channelGroup Channel group index.
  409. * param config Pointer to the "adc16_channel_config_t" structure for the conversion channel.
  410. */
  411. void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config)
  412. {
  413. assert(channelGroup < ADC_SC1_COUNT);
  414. assert(NULL != config);
  415. uint32_t sc1 = ADC_SC1_ADCH(config->channelNumber); /* Set the channel number. */
  416. #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
  417. /* Enable the differential conversion. */
  418. if (true == config->enableDifferentialConversion)
  419. {
  420. sc1 |= ADC_SC1_DIFF_MASK;
  421. }
  422. #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
  423. /* Enable the interrupt when the conversion is done. */
  424. if (true == config->enableInterruptOnConversionCompleted)
  425. {
  426. sc1 |= ADC_SC1_AIEN_MASK;
  427. }
  428. base->SC1[channelGroup] = sc1;
  429. }
  430. /*!
  431. * brief Gets the status flags of channel.
  432. *
  433. * param base ADC16 peripheral base address.
  434. * param channelGroup Channel group index.
  435. *
  436. * return Flags' mask if indicated flags are asserted. See "_adc16_channel_status_flags".
  437. */
  438. uint32_t ADC16_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup)
  439. {
  440. assert(channelGroup < ADC_SC1_COUNT);
  441. uint32_t ret = 0U;
  442. if (0U != (base->SC1[channelGroup] & ADC_SC1_COCO_MASK))
  443. {
  444. ret |= (uint32_t)kADC16_ChannelConversionDoneFlag;
  445. }
  446. return ret;
  447. }