fsl_lpadc.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /*
  2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2020 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_lpadc.h"
  9. /* Component ID definition, used by tools. */
  10. #ifndef FSL_COMPONENT_ID
  11. #define FSL_COMPONENT_ID "platform.drivers.lpadc"
  12. #endif
  13. /*******************************************************************************
  14. * Prototypes
  15. ******************************************************************************/
  16. /*!
  17. * @brief Get instance number for LPADC module.
  18. *
  19. * @param base LPADC peripheral base address
  20. */
  21. static uint32_t LPADC_GetInstance(ADC_Type *base);
  22. /*******************************************************************************
  23. * Variables
  24. ******************************************************************************/
  25. /*! @brief Pointers to LPADC bases for each instance. */
  26. static ADC_Type *const s_lpadcBases[] = ADC_BASE_PTRS;
  27. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  28. /*! @brief Pointers to LPADC clocks for each instance. */
  29. static const clock_ip_name_t s_lpadcClocks[] = LPADC_CLOCKS;
  30. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  31. /*******************************************************************************
  32. * Code
  33. ******************************************************************************/
  34. static uint32_t LPADC_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_lpadcBases); instance++)
  39. {
  40. if (s_lpadcBases[instance] == base)
  41. {
  42. break;
  43. }
  44. }
  45. assert(instance < ARRAY_SIZE(s_lpadcBases));
  46. return instance;
  47. }
  48. /*!
  49. * brief Initializes the LPADC module.
  50. *
  51. * param base LPADC peripheral base address.
  52. * param config Pointer to configuration structure. See "lpadc_config_t".
  53. */
  54. void LPADC_Init(ADC_Type *base, const lpadc_config_t *config)
  55. {
  56. /* Check if the pointer is available. */
  57. assert(config != NULL);
  58. uint32_t tmp32 = 0U;
  59. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  60. /* Enable the clock for LPADC instance. */
  61. (void)CLOCK_EnableClock(s_lpadcClocks[LPADC_GetInstance(base)]);
  62. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  63. /* Reset the module. */
  64. LPADC_DoResetConfig(base);
  65. #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
  66. LPADC_DoResetFIFO0(base);
  67. LPADC_DoResetFIFO1(base);
  68. #else
  69. LPADC_DoResetFIFO(base);
  70. #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
  71. /* Disable the module before setting configuration. */
  72. LPADC_Enable(base, false);
  73. /* Configure the module generally. */
  74. if (config->enableInDozeMode)
  75. {
  76. base->CTRL &= ~ADC_CTRL_DOZEN_MASK;
  77. }
  78. else
  79. {
  80. base->CTRL |= ADC_CTRL_DOZEN_MASK;
  81. }
  82. #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
  83. /* Set calibration average mode. */
  84. base->CTRL |= ADC_CTRL_CAL_AVGS(config->conversionAverageMode);
  85. #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
  86. /* ADCx_CFG. */
  87. #if defined(FSL_FEATURE_LPADC_HAS_CFG_ADCKEN) && FSL_FEATURE_LPADC_HAS_CFG_ADCKEN
  88. if (config->enableInternalClock)
  89. {
  90. tmp32 |= ADC_CFG_ADCKEN_MASK;
  91. }
  92. #endif /* FSL_FEATURE_LPADC_HAS_CFG_ADCKEN */
  93. #if defined(FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG) && FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG
  94. if (config->enableVref1LowVoltage)
  95. {
  96. tmp32 |= ADC_CFG_VREF1RNG_MASK;
  97. }
  98. #endif /* FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG */
  99. if (config->enableAnalogPreliminary)
  100. {
  101. tmp32 |= ADC_CFG_PWREN_MASK;
  102. }
  103. tmp32 |= ADC_CFG_PUDLY(config->powerUpDelay) /* Power up delay. */
  104. | ADC_CFG_REFSEL(config->referenceVoltageSource) /* Reference voltage. */
  105. | ADC_CFG_PWRSEL(config->powerLevelMode) /* Power configuration. */
  106. | ADC_CFG_TPRICTRL(config->triggerPriorityPolicy); /* Trigger priority policy. */
  107. base->CFG = tmp32;
  108. /* ADCx_PAUSE. */
  109. if (config->enableConvPause)
  110. {
  111. base->PAUSE = ADC_PAUSE_PAUSEEN_MASK | ADC_PAUSE_PAUSEDLY(config->convPauseDelay);
  112. }
  113. else
  114. {
  115. base->PAUSE = 0U;
  116. }
  117. #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
  118. /* ADCx_FCTRL0. */
  119. base->FCTRL[0] = ADC_FCTRL_FWMARK(config->FIFO0Watermark);
  120. /* ADCx_FCTRL1. */
  121. base->FCTRL[1] = ADC_FCTRL_FWMARK(config->FIFO1Watermark);
  122. #else
  123. /* ADCx_FCTRL. */
  124. base->FCTRL = ADC_FCTRL_FWMARK(config->FIFOWatermark);
  125. #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
  126. /* Enable the module after setting configuration. */
  127. LPADC_Enable(base, true);
  128. }
  129. /*!
  130. * brief Gets an available pre-defined settings for initial configuration.
  131. *
  132. * This function initializes the converter configuration structure with an available settings. The default values are:
  133. * code
  134. * config->enableInDozeMode = true;
  135. * config->conversionAverageMode = kLPADC_ConversionAverage1;
  136. * config->enableAnalogPreliminary = false;
  137. * config->powerUpDelay = 0x80;
  138. * config->referenceVoltageSource = kLPADC_ReferenceVoltageAlt1;
  139. * config->powerLevelMode = kLPADC_PowerLevelAlt1;
  140. * config->triggerPriorityPolicy = kLPADC_TriggerPriorityPreemptImmediately;
  141. * config->enableConvPause = false;
  142. * config->convPauseDelay = 0U;
  143. * config->FIFO0Watermark = 0U;
  144. * config->FIFO1Watermark = 0U;
  145. * config->FIFOWatermark = 0U;
  146. * endcode
  147. * param config Pointer to configuration structure.
  148. */
  149. void LPADC_GetDefaultConfig(lpadc_config_t *config)
  150. {
  151. /* Initializes the configure structure to zero. */
  152. (void)memset(config, 0, sizeof(*config));
  153. #if defined(FSL_FEATURE_LPADC_HAS_CFG_ADCKEN) && FSL_FEATURE_LPADC_HAS_CFG_ADCKEN
  154. config->enableInternalClock = false;
  155. #endif /* FSL_FEATURE_LPADC_HAS_CFG_ADCKEN */
  156. #if defined(FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG) && FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG
  157. config->enableVref1LowVoltage = false;
  158. #endif /* FSL_FEATURE_LPADC_HAS_CFG_VREF1RNG */
  159. config->enableInDozeMode = true;
  160. #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
  161. /* Set calibration average mode. */
  162. config->conversionAverageMode = kLPADC_ConversionAverage1;
  163. #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
  164. config->enableAnalogPreliminary = false;
  165. config->powerUpDelay = 0x80;
  166. config->referenceVoltageSource = kLPADC_ReferenceVoltageAlt1;
  167. config->powerLevelMode = kLPADC_PowerLevelAlt1;
  168. config->triggerPriorityPolicy = kLPADC_TriggerPriorityPreemptImmediately;
  169. config->enableConvPause = false;
  170. config->convPauseDelay = 0U;
  171. #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
  172. config->FIFO0Watermark = 0U;
  173. config->FIFO1Watermark = 0U;
  174. #else
  175. config->FIFOWatermark = 0U;
  176. #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
  177. }
  178. /*!
  179. * brief De-initializes the LPADC module.
  180. *
  181. * param base LPADC peripheral base address.
  182. */
  183. void LPADC_Deinit(ADC_Type *base)
  184. {
  185. /* Disable the module. */
  186. LPADC_Enable(base, false);
  187. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  188. /* Gate the clock. */
  189. (void)CLOCK_DisableClock(s_lpadcClocks[LPADC_GetInstance(base)]);
  190. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  191. }
  192. #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
  193. /*!
  194. * brief Get the result in conversion FIFOn.
  195. *
  196. * param base LPADC peripheral base address.
  197. * param result Pointer to structure variable that keeps the conversion result in conversion FIFOn.
  198. * param index Result FIFO index.
  199. *
  200. * return Status whether FIFOn entry is valid.
  201. */
  202. bool LPADC_GetConvResult(ADC_Type *base, lpadc_conv_result_t *result, uint8_t index)
  203. {
  204. assert(result != NULL); /* Check if the input pointer is available. */
  205. uint32_t tmp32;
  206. tmp32 = base->RESFIFO[index];
  207. if (0U == (ADC_RESFIFO_VALID_MASK & tmp32))
  208. {
  209. return false; /* FIFO is empty. Discard any read from RESFIFO. */
  210. }
  211. result->commandIdSource = (tmp32 & ADC_RESFIFO_CMDSRC_MASK) >> ADC_RESFIFO_CMDSRC_SHIFT;
  212. result->loopCountIndex = (tmp32 & ADC_RESFIFO_LOOPCNT_MASK) >> ADC_RESFIFO_LOOPCNT_SHIFT;
  213. result->triggerIdSource = (tmp32 & ADC_RESFIFO_TSRC_MASK) >> ADC_RESFIFO_TSRC_SHIFT;
  214. result->convValue = (uint16_t)(tmp32 & ADC_RESFIFO_D_MASK);
  215. return true;
  216. }
  217. #else
  218. /*!
  219. * brief Get the result in conversion FIFO.
  220. *
  221. * param base LPADC peripheral base address.
  222. * param result Pointer to structure variable that keeps the conversion result in conversion FIFO.
  223. *
  224. * return Status whether FIFO entry is valid.
  225. */
  226. bool LPADC_GetConvResult(ADC_Type *base, lpadc_conv_result_t *result)
  227. {
  228. assert(result != NULL); /* Check if the input pointer is available. */
  229. uint32_t tmp32;
  230. tmp32 = base->RESFIFO;
  231. if (0U == (ADC_RESFIFO_VALID_MASK & tmp32))
  232. {
  233. return false; /* FIFO is empty. Discard any read from RESFIFO. */
  234. }
  235. result->commandIdSource = (tmp32 & ADC_RESFIFO_CMDSRC_MASK) >> ADC_RESFIFO_CMDSRC_SHIFT;
  236. result->loopCountIndex = (tmp32 & ADC_RESFIFO_LOOPCNT_MASK) >> ADC_RESFIFO_LOOPCNT_SHIFT;
  237. result->triggerIdSource = (tmp32 & ADC_RESFIFO_TSRC_MASK) >> ADC_RESFIFO_TSRC_SHIFT;
  238. result->convValue = (uint16_t)(tmp32 & ADC_RESFIFO_D_MASK);
  239. return true;
  240. }
  241. #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
  242. /*!
  243. * brief Configure the conversion trigger source.
  244. *
  245. * Each programmable trigger can launch the conversion command in command buffer.
  246. *
  247. * param base LPADC peripheral base address.
  248. * param triggerId ID for each trigger. Typically, the available value range is from 0.
  249. * param config Pointer to configuration structure. See to #lpadc_conv_trigger_config_t.
  250. */
  251. void LPADC_SetConvTriggerConfig(ADC_Type *base, uint32_t triggerId, const lpadc_conv_trigger_config_t *config)
  252. {
  253. assert(triggerId < ADC_TCTRL_COUNT); /* Check if the triggerId is available in this device. */
  254. assert(config != NULL); /* Check if the input pointer is available. */
  255. uint32_t tmp32;
  256. tmp32 = ADC_TCTRL_TCMD(config->targetCommandId) /* Trigger command select. */
  257. | ADC_TCTRL_TDLY(config->delayPower) /* Trigger delay select. */
  258. | ADC_TCTRL_TPRI(config->priority) /* Trigger priority setting. */
  259. #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
  260. | ADC_TCTRL_FIFO_SEL_A(config->channelAFIFOSelect)
  261. #if !(defined(FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B) && FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B)
  262. | ADC_TCTRL_FIFO_SEL_B(config->channelBFIFOSelect)
  263. #endif /* FSL_FEATURE_LPADC_HAS_NO_TCTRL_FIFO_SEL_B */
  264. #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
  265. ;
  266. if (config->enableHardwareTrigger)
  267. {
  268. tmp32 |= ADC_TCTRL_HTEN_MASK;
  269. }
  270. base->TCTRL[triggerId] = tmp32;
  271. }
  272. /*!
  273. * brief Gets an available pre-defined settings for trigger's configuration.
  274. *
  275. * This function initializes the trigger's configuration structure with an available settings. The default values are:
  276. * code
  277. * config->commandIdSource = 0U;
  278. * config->loopCountIndex = 0U;
  279. * config->triggerIdSource = 0U;
  280. * config->enableHardwareTrigger = false;
  281. * config->channelAFIFOSelect = 0U;
  282. * config->channelBFIFOSelect = 0U;
  283. * endcode
  284. * param config Pointer to configuration structure.
  285. */
  286. void LPADC_GetDefaultConvTriggerConfig(lpadc_conv_trigger_config_t *config)
  287. {
  288. assert(config != NULL); /* Check if the input pointer is available. */
  289. /* Initializes the configure structure to zero. */
  290. (void)memset(config, 0, sizeof(*config));
  291. config->targetCommandId = 0U;
  292. config->delayPower = 0U;
  293. config->priority = 0U;
  294. #if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2))
  295. config->channelAFIFOSelect = 0U;
  296. config->channelBFIFOSelect = 0U;
  297. #endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
  298. config->enableHardwareTrigger = false;
  299. }
  300. /*!
  301. * brief Configure conversion command.
  302. *
  303. * param base LPADC peripheral base address.
  304. * param commandId ID for command in command buffer. Typically, the available value range is 1 - 15.
  305. * param config Pointer to configuration structure. See to #lpadc_conv_command_config_t.
  306. */
  307. void LPADC_SetConvCommandConfig(ADC_Type *base, uint32_t commandId, const lpadc_conv_command_config_t *config)
  308. {
  309. assert(commandId < (ADC_CMDL_COUNT + 1U)); /* Check if the commandId is available on this device. */
  310. assert(config != NULL); /* Check if the input pointer is available. */
  311. uint32_t tmp32 = 0;
  312. commandId--; /* The available command number are 1-15, while the index of register group are 0-14. */
  313. /* ADCx_CMDL. */
  314. tmp32 = ADC_CMDL_ADCH(config->channelNumber); /* Channel number. */
  315. #if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
  316. tmp32 |= ADC_CMDL_CSCALE(config->sampleScaleMode); /* Full/Part scale input voltage. */
  317. #endif /* FSL_FEATURE_LPADC_HAS_CMDL_CSCALE */
  318. #if defined(FSL_FEATURE_LPADC_HAS_CMDL_CTYPE) && FSL_FEATURE_LPADC_HAS_CMDL_CTYPE
  319. tmp32 |= ADC_CMDL_CTYPE(config->sampleChannelMode);
  320. #else
  321. switch (config->sampleChannelMode) /* Sample input. */
  322. {
  323. case kLPADC_SampleChannelSingleEndSideB:
  324. tmp32 |= ADC_CMDL_ABSEL_MASK;
  325. break;
  326. #if defined(FSL_FEATURE_LPADC_HAS_CMDL_DIFF) && FSL_FEATURE_LPADC_HAS_CMDL_DIFF
  327. case kLPADC_SampleChannelDiffBothSideAB:
  328. tmp32 |= ADC_CMDL_DIFF_MASK;
  329. break;
  330. case kLPADC_SampleChannelDiffBothSideBA:
  331. tmp32 |= ADC_CMDL_ABSEL_MASK | ADC_CMDL_DIFF_MASK;
  332. break;
  333. #endif /* FSL_FEATURE_LPADC_HAS_CMDL_DIFF */
  334. default: /* kLPADC_SampleChannelSingleEndSideA. */
  335. break;
  336. }
  337. #endif /* FSL_FEATURE_LPADC_HAS_CMDL_CTYPE */
  338. #if defined(FSL_FEATURE_LPADC_HAS_CMDL_MODE) && FSL_FEATURE_LPADC_HAS_CMDL_MODE
  339. tmp32 |= ADC_CMDL_MODE(config->conversionResolutionMode);
  340. #endif /* FSL_FEATURE_LPADC_HAS_CMDL_MODE */
  341. base->CMD[commandId].CMDL = tmp32;
  342. /* ADCx_CMDH. */
  343. tmp32 = ADC_CMDH_NEXT(config->chainedNextCommandNumber) /* Next Command Select. */
  344. | ADC_CMDH_LOOP(config->loopCount) /* Loop Count Select. */
  345. | ADC_CMDH_AVGS(config->hardwareAverageMode) /* Hardware Average Select. */
  346. | ADC_CMDH_STS(config->sampleTimeMode) /* Sample Time Select. */
  347. | ADC_CMDH_CMPEN(config->hardwareCompareMode); /* Hardware compare enable. */
  348. #if (defined(FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG) && FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG)
  349. if (config->enableWaitTrigger)
  350. {
  351. tmp32 |= ADC_CMDH_WAIT_TRIG_MASK; /* Wait trigger enable. */
  352. }
  353. #endif /* FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG */
  354. if (config->enableAutoChannelIncrement)
  355. {
  356. tmp32 |= ADC_CMDH_LWI_MASK;
  357. }
  358. base->CMD[commandId].CMDH = tmp32;
  359. /* Hardware compare settings.
  360. * Not all Command Buffers have an associated Compare Value register. The compare function is only available on
  361. * Command Buffers that have a corresponding Compare Value register.
  362. */
  363. if (kLPADC_HardwareCompareDisabled != config->hardwareCompareMode)
  364. {
  365. /* Check if the hardware compare feature is available for indicated command buffer. */
  366. assert(commandId < ADC_CV_COUNT);
  367. /* Set CV register. */
  368. base->CV[commandId] = ADC_CV_CVH(config->hardwareCompareValueHigh) /* Compare value high. */
  369. | ADC_CV_CVL(config->hardwareCompareValueLow); /* Compare value low. */
  370. }
  371. }
  372. /*!
  373. * brief Gets an available pre-defined settings for conversion command's configuration.
  374. *
  375. * This function initializes the conversion command's configuration structure with an available settings. The default
  376. * values are:
  377. * code
  378. * config->sampleScaleMode = kLPADC_SampleFullScale;
  379. * config->channelSampleMode = kLPADC_SampleChannelSingleEndSideA;
  380. * config->channelNumber = 0U;
  381. * config->chainedNextCmdNumber = 0U;
  382. * config->enableAutoChannelIncrement = false;
  383. * config->loopCount = 0U;
  384. * config->hardwareAverageMode = kLPADC_HardwareAverageCount1;
  385. * config->sampleTimeMode = kLPADC_SampleTimeADCK3;
  386. * config->hardwareCompareMode = kLPADC_HardwareCompareDisabled;
  387. * config->hardwareCompareValueHigh = 0U;
  388. * config->hardwareCompareValueLow = 0U;
  389. * config->conversionResolutionMode = kLPADC_ConversionResolutionStandard;
  390. * config->enableWaitTrigger = false;
  391. * endcode
  392. * param config Pointer to configuration structure.
  393. */
  394. void LPADC_GetDefaultConvCommandConfig(lpadc_conv_command_config_t *config)
  395. {
  396. assert(config != NULL); /* Check if the input pointer is available. */
  397. /* Initializes the configure structure to zero. */
  398. (void)memset(config, 0, sizeof(*config));
  399. #if defined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) && FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
  400. config->sampleScaleMode = kLPADC_SampleFullScale;
  401. #endif /* FSL_FEATURE_LPADC_HAS_CMDL_CSCALE */
  402. config->sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
  403. config->channelNumber = 0U;
  404. config->chainedNextCommandNumber = 0U; /* No next command defined. */
  405. config->enableAutoChannelIncrement = false;
  406. config->loopCount = 0U;
  407. config->hardwareAverageMode = kLPADC_HardwareAverageCount1;
  408. config->sampleTimeMode = kLPADC_SampleTimeADCK3;
  409. config->hardwareCompareMode = kLPADC_HardwareCompareDisabled;
  410. config->hardwareCompareValueHigh = 0U; /* No used. */
  411. config->hardwareCompareValueLow = 0U; /* No used. */
  412. #if defined(FSL_FEATURE_LPADC_HAS_CMDL_MODE) && FSL_FEATURE_LPADC_HAS_CMDL_MODE
  413. config->conversionResolutionMode = kLPADC_ConversionResolutionStandard;
  414. #endif /* FSL_FEATURE_LPADC_HAS_CMDL_MODE */
  415. #if defined(FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG) && FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG
  416. config->enableWaitTrigger = false;
  417. #endif /* FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG */
  418. }
  419. #if defined(FSL_FEATURE_LPADC_HAS_CFG_CALOFS) && FSL_FEATURE_LPADC_HAS_CFG_CALOFS
  420. /*!
  421. * brief Enable the calibration function.
  422. *
  423. * When CALOFS is set, the ADC is configured to perform a calibration function anytime the ADC executes
  424. * a conversion. Any channel selected is ignored and the value returned in the RESFIFO is a signed value
  425. * between -31 and 31. -32 is not a valid and is never a returned value. Software should copy the lower 6-
  426. * bits of the conversion result stored in the RESFIFO after a completed calibration conversion to the
  427. * OFSTRIM field. The OFSTRIM field is used in normal operation for offset correction.
  428. *
  429. * param base LPADC peripheral base address.
  430. * param enable switcher to the calibration function.
  431. */
  432. void LPADC_EnableCalibration(ADC_Type *base, bool enable)
  433. {
  434. LPADC_Enable(base, false);
  435. if (enable)
  436. {
  437. base->CFG |= ADC_CFG_CALOFS_MASK;
  438. }
  439. else
  440. {
  441. base->CFG &= ~ADC_CFG_CALOFS_MASK;
  442. }
  443. LPADC_Enable(base, true);
  444. }
  445. #if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) && FSL_FEATURE_LPADC_HAS_OFSTRIM
  446. /*!
  447. * brief Do auto calibration.
  448. *
  449. * Calibration function should be executed before using converter in application. It used the software trigger and a
  450. * dummy conversion, get the offset and write them into the OFSTRIM register. It called some of functional API
  451. * including: -LPADC_EnableCalibration(...) -LPADC_LPADC_SetOffsetValue(...) -LPADC_SetConvCommandConfig(...)
  452. * -LPADC_SetConvTriggerConfig(...)
  453. *
  454. * param base LPADC peripheral base address.
  455. */
  456. void LPADC_DoAutoCalibration(ADC_Type *base)
  457. {
  458. assert(0u == LPADC_GetConvResultCount(base));
  459. uint32_t mLpadcCMDL;
  460. uint32_t mLpadcCMDH;
  461. uint32_t mLpadcTrigger;
  462. lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct;
  463. lpadc_conv_command_config_t mLpadcCommandConfigStruct;
  464. lpadc_conv_result_t mLpadcResultConfigStruct;
  465. /* Enable the calibration function. */
  466. LPADC_EnableCalibration(base, true);
  467. /* Keep the CMD and TRG state here and restore it later if the calibration completes.*/
  468. mLpadcCMDL = base->CMD[0].CMDL; /* CMD1L. */
  469. mLpadcCMDH = base->CMD[0].CMDH; /* CMD1H. */
  470. mLpadcTrigger = base->TCTRL[0]; /* Trigger0. */
  471. /* Set trigger0 configuration - for software trigger. */
  472. LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct);
  473. mLpadcTriggerConfigStruct.targetCommandId = 1U; /* CMD1 is executed. */
  474. LPADC_SetConvTriggerConfig(base, 0U, &mLpadcTriggerConfigStruct); /* Configurate the trigger0. */
  475. /* Set conversion CMD configuration. */
  476. LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
  477. mLpadcCommandConfigStruct.hardwareAverageMode = kLPADC_HardwareAverageCount128;
  478. LPADC_SetConvCommandConfig(base, 1U, &mLpadcCommandConfigStruct); /* Set CMD1 configuration. */
  479. /* Do calibration. */
  480. LPADC_DoSoftwareTrigger(base, 1U); /* 1U is trigger0 mask. */
  481. while (!LPADC_GetConvResult(base, &mLpadcResultConfigStruct))
  482. {
  483. }
  484. /* The valid bits of data are bits 14:3 in the RESFIFO register. */
  485. LPADC_SetOffsetValue(base, (uint32_t)(mLpadcResultConfigStruct.convValue) >> 3UL);
  486. /* Disable the calibration function. */
  487. LPADC_EnableCalibration(base, false);
  488. /* restore CMD and TRG registers. */
  489. base->CMD[0].CMDL = mLpadcCMDL; /* CMD1L. */
  490. base->CMD[0].CMDH = mLpadcCMDH; /* CMD1H. */
  491. base->TCTRL[0] = mLpadcTrigger; /* Trigger0. */
  492. }
  493. #endif /* FSL_FEATURE_LPADC_HAS_OFSTRIM */
  494. #endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
  495. #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS
  496. /*!
  497. * brief Do offset calibration.
  498. *
  499. * param base LPADC peripheral base address.
  500. */
  501. void LPADC_DoOffsetCalibration(ADC_Type *base)
  502. {
  503. LPADC_EnableOffsetCalibration(base, true);
  504. while (ADC_STAT_CAL_RDY_MASK != (base->STAT & ADC_STAT_CAL_RDY_MASK))
  505. {
  506. }
  507. }
  508. #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ
  509. /*!
  510. * brief Do auto calibration.
  511. *
  512. * param base LPADC peripheral base address.
  513. */
  514. void LPADC_DoAutoCalibration(ADC_Type *base)
  515. {
  516. assert((0u == LPADC_GetConvResultCount(base, 0)) && (0u == LPADC_GetConvResultCount(base, 1)));
  517. uint32_t GCCa;
  518. uint32_t GCCb;
  519. uint32_t GCRa;
  520. uint32_t GCRb;
  521. /* Request gain calibration. */
  522. base->CTRL |= ADC_CTRL_CAL_REQ_MASK;
  523. while ((ADC_GCC_RDY_MASK != (base->GCC[0] & ADC_GCC_RDY_MASK)) ||
  524. (ADC_GCC_RDY_MASK != (base->GCC[1] & ADC_GCC_RDY_MASK)))
  525. {
  526. }
  527. /* Calculate gain offset. */
  528. GCCa = (base->GCC[0] & ADC_GCC_GAIN_CAL_MASK);
  529. GCCb = (base->GCC[1] & ADC_GCC_GAIN_CAL_MASK);
  530. GCRa = (uint16_t)((GCCa << 16U) /
  531. (0x1FFFFU - GCCa)); /* Gain_CalA = (131072 / (131072-(ADC_GCC_GAIN_CAL(ADC0->GCC[0])) - 1. */
  532. GCRb = (uint16_t)((GCCb << 16U) /
  533. (0x1FFFFU - GCCb)); /* Gain_CalB = (131072 / (131072-(ADC_GCC_GAIN_CAL(ADC0->GCC[1])) - 1. */
  534. base->GCR[0] = ADC_GCR_GCALR(GCRa);
  535. base->GCR[1] = ADC_GCR_GCALR(GCRb);
  536. /* Indicate the values are valid. */
  537. base->GCR[0] |= ADC_GCR_RDY_MASK;
  538. base->GCR[1] |= ADC_GCR_RDY_MASK;
  539. while (ADC_STAT_CAL_RDY_MASK != (base->STAT & ADC_STAT_CAL_RDY_MASK))
  540. {
  541. }
  542. }
  543. #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ */
  544. #endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */