fsl_cmp.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*
  2. * The Clear BSD License
  3. * Copyright (c) 2015, 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_cmp.h"
  35. /*******************************************************************************
  36. * Prototypes
  37. ******************************************************************************/
  38. /*!
  39. * @brief Get instance number for CMP module.
  40. *
  41. * @param base CMP peripheral base address
  42. */
  43. static uint32_t CMP_GetInstance(CMP_Type *base);
  44. /*******************************************************************************
  45. * Variables
  46. ******************************************************************************/
  47. /*! @brief Pointers to CMP bases for each instance. */
  48. static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS;
  49. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  50. /*! @brief Pointers to CMP clocks for each instance. */
  51. static const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS;
  52. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  53. /*******************************************************************************
  54. * Codes
  55. ******************************************************************************/
  56. static uint32_t CMP_GetInstance(CMP_Type *base)
  57. {
  58. uint32_t instance;
  59. /* Find the instance index from base address mappings. */
  60. for (instance = 0; instance < ARRAY_SIZE(s_cmpBases); instance++)
  61. {
  62. if (s_cmpBases[instance] == base)
  63. {
  64. break;
  65. }
  66. }
  67. assert(instance < ARRAY_SIZE(s_cmpBases));
  68. return instance;
  69. }
  70. void CMP_Init(CMP_Type *base, const cmp_config_t *config)
  71. {
  72. assert(NULL != config);
  73. uint8_t tmp8;
  74. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  75. /* Enable the clock. */
  76. CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]);
  77. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  78. /* Configure. */
  79. CMP_Enable(base, false); /* Disable the CMP module during configuring. */
  80. /* CMPx_CR1. */
  81. tmp8 = base->CR1 & ~(CMP_CR1_PMODE_MASK | CMP_CR1_INV_MASK | CMP_CR1_COS_MASK | CMP_CR1_OPE_MASK);
  82. if (config->enableHighSpeed)
  83. {
  84. tmp8 |= CMP_CR1_PMODE_MASK;
  85. }
  86. if (config->enableInvertOutput)
  87. {
  88. tmp8 |= CMP_CR1_INV_MASK;
  89. }
  90. if (config->useUnfilteredOutput)
  91. {
  92. tmp8 |= CMP_CR1_COS_MASK;
  93. }
  94. if (config->enablePinOut)
  95. {
  96. tmp8 |= CMP_CR1_OPE_MASK;
  97. }
  98. #if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
  99. if (config->enableTriggerMode)
  100. {
  101. tmp8 |= CMP_CR1_TRIGM_MASK;
  102. }
  103. else
  104. {
  105. tmp8 &= ~CMP_CR1_TRIGM_MASK;
  106. }
  107. #endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
  108. base->CR1 = tmp8;
  109. /* CMPx_CR0. */
  110. tmp8 = base->CR0 & ~CMP_CR0_HYSTCTR_MASK;
  111. tmp8 |= CMP_CR0_HYSTCTR(config->hysteresisMode);
  112. base->CR0 = tmp8;
  113. CMP_Enable(base, config->enableCmp); /* Enable the CMP module after configured or not. */
  114. }
  115. void CMP_Deinit(CMP_Type *base)
  116. {
  117. /* Disable the CMP module. */
  118. CMP_Enable(base, false);
  119. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  120. /* Disable the clock. */
  121. CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]);
  122. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  123. }
  124. void CMP_GetDefaultConfig(cmp_config_t *config)
  125. {
  126. assert(NULL != config);
  127. config->enableCmp = true; /* Enable the CMP module after initialization. */
  128. config->hysteresisMode = kCMP_HysteresisLevel0;
  129. config->enableHighSpeed = false;
  130. config->enableInvertOutput = false;
  131. config->useUnfilteredOutput = false;
  132. config->enablePinOut = false;
  133. #if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
  134. config->enableTriggerMode = false;
  135. #endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
  136. }
  137. void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel)
  138. {
  139. uint8_t tmp8 = base->MUXCR;
  140. tmp8 &= ~(CMP_MUXCR_PSEL_MASK | CMP_MUXCR_MSEL_MASK);
  141. tmp8 |= CMP_MUXCR_PSEL(positiveChannel) | CMP_MUXCR_MSEL(negativeChannel);
  142. base->MUXCR = tmp8;
  143. }
  144. #if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA
  145. void CMP_EnableDMA(CMP_Type *base, bool enable)
  146. {
  147. uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
  148. if (enable)
  149. {
  150. tmp8 |= CMP_SCR_DMAEN_MASK;
  151. }
  152. else
  153. {
  154. tmp8 &= ~CMP_SCR_DMAEN_MASK;
  155. }
  156. base->SCR = tmp8;
  157. }
  158. #endif /* FSL_FEATURE_CMP_HAS_DMA */
  159. void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config)
  160. {
  161. assert(NULL != config);
  162. uint8_t tmp8;
  163. #if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT
  164. /* Choose the clock source for sampling. */
  165. if (config->enableSample)
  166. {
  167. base->CR1 |= CMP_CR1_SE_MASK; /* Choose the external SAMPLE clock. */
  168. }
  169. else
  170. {
  171. base->CR1 &= ~CMP_CR1_SE_MASK; /* Choose the internal divided bus clock. */
  172. }
  173. #endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */
  174. /* Set the filter count. */
  175. tmp8 = base->CR0 & ~CMP_CR0_FILTER_CNT_MASK;
  176. tmp8 |= CMP_CR0_FILTER_CNT(config->filterCount);
  177. base->CR0 = tmp8;
  178. /* Set the filter period. It is used as the divider to bus clock. */
  179. base->FPR = CMP_FPR_FILT_PER(config->filterPeriod);
  180. }
  181. void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config)
  182. {
  183. uint8_t tmp8 = 0U;
  184. if (NULL == config)
  185. {
  186. /* Passing "NULL" as input parameter means no available configuration. So the DAC feature is disabled.*/
  187. base->DACCR = 0U;
  188. return;
  189. }
  190. /* CMPx_DACCR. */
  191. tmp8 |= CMP_DACCR_DACEN_MASK; /* Enable the internal DAC. */
  192. if (kCMP_VrefSourceVin2 == config->referenceVoltageSource)
  193. {
  194. tmp8 |= CMP_DACCR_VRSEL_MASK;
  195. }
  196. tmp8 |= CMP_DACCR_VOSEL(config->DACValue);
  197. base->DACCR = tmp8;
  198. }
  199. void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask)
  200. {
  201. uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
  202. if (0U != (kCMP_OutputRisingInterruptEnable & mask))
  203. {
  204. tmp8 |= CMP_SCR_IER_MASK;
  205. }
  206. if (0U != (kCMP_OutputFallingInterruptEnable & mask))
  207. {
  208. tmp8 |= CMP_SCR_IEF_MASK;
  209. }
  210. base->SCR = tmp8;
  211. }
  212. void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask)
  213. {
  214. uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
  215. if (0U != (kCMP_OutputRisingInterruptEnable & mask))
  216. {
  217. tmp8 &= ~CMP_SCR_IER_MASK;
  218. }
  219. if (0U != (kCMP_OutputFallingInterruptEnable & mask))
  220. {
  221. tmp8 &= ~CMP_SCR_IEF_MASK;
  222. }
  223. base->SCR = tmp8;
  224. }
  225. uint32_t CMP_GetStatusFlags(CMP_Type *base)
  226. {
  227. uint32_t ret32 = 0U;
  228. if (0U != (CMP_SCR_CFR_MASK & base->SCR))
  229. {
  230. ret32 |= kCMP_OutputRisingEventFlag;
  231. }
  232. if (0U != (CMP_SCR_CFF_MASK & base->SCR))
  233. {
  234. ret32 |= kCMP_OutputFallingEventFlag;
  235. }
  236. if (0U != (CMP_SCR_COUT_MASK & base->SCR))
  237. {
  238. ret32 |= kCMP_OutputAssertEventFlag;
  239. }
  240. return ret32;
  241. }
  242. void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask)
  243. {
  244. uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
  245. if (0U != (kCMP_OutputRisingEventFlag & mask))
  246. {
  247. tmp8 |= CMP_SCR_CFR_MASK;
  248. }
  249. if (0U != (kCMP_OutputFallingEventFlag & mask))
  250. {
  251. tmp8 |= CMP_SCR_CFF_MASK;
  252. }
  253. base->SCR = tmp8;
  254. }