fsl_cmp.c 9.1 KB

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