Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 

372 řádky
11 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_cmp.h"
  9. /* Component ID definition, used by tools. */
  10. #ifndef FSL_COMPONENT_ID
  11. #define FSL_COMPONENT_ID "platform.drivers.cmp"
  12. #endif
  13. /*******************************************************************************
  14. * Prototypes
  15. ******************************************************************************/
  16. /*!
  17. * @brief Get instance number for CMP module.
  18. *
  19. * @param base CMP peripheral base address
  20. */
  21. static uint32_t CMP_GetInstance(CMP_Type *base);
  22. /*******************************************************************************
  23. * Variables
  24. ******************************************************************************/
  25. /*! @brief Pointers to CMP bases for each instance. */
  26. static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS;
  27. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  28. /*! @brief Pointers to CMP clocks for each instance. */
  29. static const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS;
  30. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  31. /*******************************************************************************
  32. * Codes
  33. ******************************************************************************/
  34. static uint32_t CMP_GetInstance(CMP_Type *base)
  35. {
  36. uint32_t instance;
  37. /* Find the instance index from base address mappings. */
  38. for (instance = 0; instance < ARRAY_SIZE(s_cmpBases); instance++)
  39. {
  40. if (s_cmpBases[instance] == base)
  41. {
  42. break;
  43. }
  44. }
  45. assert(instance < ARRAY_SIZE(s_cmpBases));
  46. return instance;
  47. }
  48. /*!
  49. * brief Initializes the CMP.
  50. *
  51. * This function initializes the CMP module. The operations included are as follows.
  52. * - Enabling the clock for CMP module.
  53. * - Configuring the comparator.
  54. * - Enabling the CMP module.
  55. * Note that for some devices, multiple CMP instances share the same clock gate. In this case, to enable the clock for
  56. * any instance enables all CMPs. See the appropriate MCU reference manual for the clock assignment of the CMP.
  57. *
  58. * param base CMP peripheral base address.
  59. * param config Pointer to the configuration structure.
  60. */
  61. void CMP_Init(CMP_Type *base, const cmp_config_t *config)
  62. {
  63. assert(NULL != config);
  64. uint8_t tmp8;
  65. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  66. /* Enable the clock. */
  67. CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]);
  68. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  69. /* Configure. */
  70. CMP_Enable(base, false); /* Disable the CMP module during configuring. */
  71. /* CMPx_CR1. */
  72. tmp8 = (uint8_t)(base->CR1 & ~(CMP_CR1_PMODE_MASK | CMP_CR1_INV_MASK | CMP_CR1_COS_MASK | CMP_CR1_OPE_MASK));
  73. if (true == config->enableHighSpeed)
  74. {
  75. tmp8 |= CMP_CR1_PMODE_MASK;
  76. }
  77. if (true == config->enableInvertOutput)
  78. {
  79. tmp8 |= CMP_CR1_INV_MASK;
  80. }
  81. if (true == config->useUnfilteredOutput)
  82. {
  83. tmp8 |= CMP_CR1_COS_MASK;
  84. }
  85. if (true == config->enablePinOut)
  86. {
  87. tmp8 |= CMP_CR1_OPE_MASK;
  88. }
  89. #if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
  90. if (true == config->enableTriggerMode)
  91. {
  92. tmp8 |= CMP_CR1_TRIGM_MASK;
  93. }
  94. else
  95. {
  96. tmp8 &= ~(uint8_t)CMP_CR1_TRIGM_MASK;
  97. }
  98. #endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
  99. base->CR1 = tmp8;
  100. /* CMPx_CR0. */
  101. tmp8 = base->CR0 & ~(uint8_t)CMP_CR0_HYSTCTR_MASK;
  102. tmp8 |= CMP_CR0_HYSTCTR(config->hysteresisMode);
  103. base->CR0 = tmp8;
  104. CMP_Enable(base, config->enableCmp); /* Enable the CMP module after configured or not. */
  105. }
  106. /*!
  107. * brief De-initializes the CMP module.
  108. *
  109. * This function de-initializes the CMP module. The operations included are as follows.
  110. * - Disabling the CMP module.
  111. * - Disabling the clock for CMP module.
  112. *
  113. * This function disables the clock for the CMP.
  114. * Note that for some devices, multiple CMP instances share the same clock gate. In this case, before disabling the
  115. * clock for the CMP, ensure that all the CMP instances are not used.
  116. *
  117. * param base CMP peripheral base address.
  118. */
  119. void CMP_Deinit(CMP_Type *base)
  120. {
  121. /* Disable the CMP module. */
  122. CMP_Enable(base, false);
  123. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  124. /* Disable the clock. */
  125. CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]);
  126. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  127. }
  128. /*!
  129. * brief Initializes the CMP user configuration structure.
  130. *
  131. * This function initializes the user configuration structure to these default values.
  132. * code
  133. * config->enableCmp = true;
  134. * config->hysteresisMode = kCMP_HysteresisLevel0;
  135. * config->enableHighSpeed = false;
  136. * config->enableInvertOutput = false;
  137. * config->useUnfilteredOutput = false;
  138. * config->enablePinOut = false;
  139. * config->enableTriggerMode = false;
  140. * endcode
  141. * param config Pointer to the configuration structure.
  142. */
  143. void CMP_GetDefaultConfig(cmp_config_t *config)
  144. {
  145. assert(NULL != config);
  146. /* Initializes the configure structure to zero. */
  147. (void)memset(config, 0, sizeof(*config));
  148. config->enableCmp = true; /* Enable the CMP module after initialization. */
  149. config->hysteresisMode = kCMP_HysteresisLevel0;
  150. config->enableHighSpeed = false;
  151. config->enableInvertOutput = false;
  152. config->useUnfilteredOutput = false;
  153. config->enablePinOut = false;
  154. #if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
  155. config->enableTriggerMode = false;
  156. #endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
  157. }
  158. /*!
  159. * brief Sets the input channels for the comparator.
  160. *
  161. * This function sets the input channels for the comparator.
  162. * Note that two input channels cannot be set the same way in the application. When the user selects the same input
  163. * from the analog mux to the positive and negative port, the comparator is disabled automatically.
  164. *
  165. * param base CMP peripheral base address.
  166. * param positiveChannel Positive side input channel number. Available range is 0-7.
  167. * param negativeChannel Negative side input channel number. Available range is 0-7.
  168. */
  169. void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel)
  170. {
  171. uint8_t tmp8 = base->MUXCR;
  172. tmp8 &= ~(uint8_t)(CMP_MUXCR_PSEL_MASK | CMP_MUXCR_MSEL_MASK);
  173. tmp8 |= CMP_MUXCR_PSEL(positiveChannel) | CMP_MUXCR_MSEL(negativeChannel);
  174. base->MUXCR = tmp8;
  175. }
  176. #if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA
  177. /*!
  178. * brief Enables/disables the DMA request for rising/falling events.
  179. *
  180. * This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of
  181. * the DMA request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from
  182. * the CMP
  183. * if the DMA is disabled.
  184. *
  185. * param base CMP peripheral base address.
  186. * param enable Enables or disables the feature.
  187. */
  188. void CMP_EnableDMA(CMP_Type *base, bool enable)
  189. {
  190. uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
  191. if (enable)
  192. {
  193. tmp8 |= CMP_SCR_DMAEN_MASK;
  194. }
  195. else
  196. {
  197. tmp8 &= ~(uint8_t)CMP_SCR_DMAEN_MASK;
  198. }
  199. base->SCR = tmp8;
  200. }
  201. #endif /* FSL_FEATURE_CMP_HAS_DMA */
  202. /*!
  203. * brief Configures the filter.
  204. *
  205. * param base CMP peripheral base address.
  206. * param config Pointer to the configuration structure.
  207. */
  208. void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config)
  209. {
  210. assert(NULL != config);
  211. uint8_t tmp8;
  212. #if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT
  213. /* Choose the clock source for sampling. */
  214. if (config->enableSample)
  215. {
  216. base->CR1 |= CMP_CR1_SE_MASK; /* Choose the external SAMPLE clock. */
  217. }
  218. else
  219. {
  220. base->CR1 &= (uint8_t)(~CMP_CR1_SE_MASK); /* Choose the internal divided bus clock. */
  221. }
  222. #endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */
  223. /* Set the filter count. */
  224. tmp8 = (uint8_t)(base->CR0 & ~CMP_CR0_FILTER_CNT_MASK);
  225. tmp8 |= CMP_CR0_FILTER_CNT(config->filterCount);
  226. base->CR0 = tmp8;
  227. /* Set the filter period. It is used as the divider to bus clock. */
  228. base->FPR = CMP_FPR_FILT_PER(config->filterPeriod);
  229. }
  230. /*!
  231. * brief Configures the internal DAC.
  232. *
  233. * param base CMP peripheral base address.
  234. * param config Pointer to the configuration structure. "NULL" disables the feature.
  235. */
  236. void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config)
  237. {
  238. uint8_t tmp8 = 0U;
  239. if (NULL == config)
  240. {
  241. /* Passing "NULL" as input parameter means no available configuration. So the DAC feature is disabled.*/
  242. base->DACCR = 0U;
  243. return;
  244. }
  245. /* CMPx_DACCR. */
  246. tmp8 |= CMP_DACCR_DACEN_MASK; /* Enable the internal DAC. */
  247. if (kCMP_VrefSourceVin2 == config->referenceVoltageSource)
  248. {
  249. tmp8 |= CMP_DACCR_VRSEL_MASK;
  250. }
  251. tmp8 |= CMP_DACCR_VOSEL(config->DACValue);
  252. base->DACCR = tmp8;
  253. }
  254. /*!
  255. * brief Enables the interrupts.
  256. *
  257. * param base CMP peripheral base address.
  258. * param mask Mask value for interrupts. See "_cmp_interrupt_enable".
  259. */
  260. void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask)
  261. {
  262. uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
  263. if (0U != ((uint32_t)kCMP_OutputRisingInterruptEnable & mask))
  264. {
  265. tmp8 |= CMP_SCR_IER_MASK;
  266. }
  267. if (0U != ((uint32_t)kCMP_OutputFallingInterruptEnable & mask))
  268. {
  269. tmp8 |= CMP_SCR_IEF_MASK;
  270. }
  271. base->SCR = tmp8;
  272. }
  273. /*!
  274. * brief Disables the interrupts.
  275. *
  276. * param base CMP peripheral base address.
  277. * param mask Mask value for interrupts. See "_cmp_interrupt_enable".
  278. */
  279. void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask)
  280. {
  281. uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
  282. if (0U != ((uint32_t)kCMP_OutputRisingInterruptEnable & mask))
  283. {
  284. tmp8 &= ~(uint8_t)CMP_SCR_IER_MASK;
  285. }
  286. if (0U != ((uint32_t)kCMP_OutputFallingInterruptEnable & mask))
  287. {
  288. tmp8 &= ~(uint8_t)CMP_SCR_IEF_MASK;
  289. }
  290. base->SCR = tmp8;
  291. }
  292. /*!
  293. * brief Gets the status flags.
  294. *
  295. * param base CMP peripheral base address.
  296. *
  297. * return Mask value for the asserted flags. See "_cmp_status_flags".
  298. */
  299. uint32_t CMP_GetStatusFlags(CMP_Type *base)
  300. {
  301. uint32_t ret32 = 0U;
  302. if (0U != (CMP_SCR_CFR_MASK & base->SCR))
  303. {
  304. ret32 |= (uint32_t)kCMP_OutputRisingEventFlag;
  305. }
  306. if (0U != (CMP_SCR_CFF_MASK & base->SCR))
  307. {
  308. ret32 |= (uint32_t)kCMP_OutputFallingEventFlag;
  309. }
  310. if (0U != (CMP_SCR_COUT_MASK & base->SCR))
  311. {
  312. ret32 |= (uint32_t)kCMP_OutputAssertEventFlag;
  313. }
  314. return ret32;
  315. }
  316. /*!
  317. * brief Clears the status flags.
  318. *
  319. * param base CMP peripheral base address.
  320. * param mask Mask value for the flags. See "_cmp_status_flags".
  321. */
  322. void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask)
  323. {
  324. uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
  325. if (0U != ((uint32_t)kCMP_OutputRisingEventFlag & mask))
  326. {
  327. tmp8 |= CMP_SCR_CFR_MASK;
  328. }
  329. if (0U != ((uint32_t)kCMP_OutputFallingEventFlag & mask))
  330. {
  331. tmp8 |= CMP_SCR_CFF_MASK;
  332. }
  333. base->SCR = tmp8;
  334. }