fsl_gint.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. * The Clear BSD License
  3. * Copyright (c) 2016, 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_gint.h"
  35. /* Component ID definition, used by tools. */
  36. #ifndef FSL_COMPONENT_ID
  37. #define FSL_COMPONENT_ID "platform.drivers.gint"
  38. #endif
  39. /*******************************************************************************
  40. * Variables
  41. ******************************************************************************/
  42. /*! @brief Pointers to GINT bases for each instance. */
  43. static GINT_Type *const s_gintBases[FSL_FEATURE_SOC_GINT_COUNT] = GINT_BASE_PTRS;
  44. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  45. /*! @brief Clocks for each instance. */
  46. static const clock_ip_name_t s_gintClocks[FSL_FEATURE_SOC_GINT_COUNT] = GINT_CLOCKS;
  47. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  48. /*! @brief Resets for each instance. */
  49. static const reset_ip_name_t s_gintResets[FSL_FEATURE_SOC_GINT_COUNT] = GINT_RSTS;
  50. /* @brief Irq number for each instance */
  51. static const IRQn_Type s_gintIRQ[FSL_FEATURE_SOC_GINT_COUNT] = GINT_IRQS;
  52. /*! @brief Callback function array for GINT(s). */
  53. static gint_cb_t s_gintCallback[FSL_FEATURE_SOC_GINT_COUNT];
  54. /*******************************************************************************
  55. * Code
  56. ******************************************************************************/
  57. static uint32_t GINT_GetInstance(GINT_Type *base)
  58. {
  59. uint32_t instance;
  60. /* Find the instance index from base address mappings. */
  61. for (instance = 0; instance < ARRAY_SIZE(s_gintBases); instance++)
  62. {
  63. if (s_gintBases[instance] == base)
  64. {
  65. break;
  66. }
  67. }
  68. assert(instance < ARRAY_SIZE(s_gintBases));
  69. return instance;
  70. }
  71. void GINT_Init(GINT_Type *base)
  72. {
  73. uint32_t instance;
  74. instance = GINT_GetInstance(base);
  75. s_gintCallback[instance] = NULL;
  76. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  77. /* Enable the peripheral clock */
  78. CLOCK_EnableClock(s_gintClocks[instance]);
  79. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  80. /* Reset the peripheral */
  81. RESET_PeripheralReset(s_gintResets[instance]);
  82. }
  83. void GINT_SetCtrl(GINT_Type *base, gint_comb_t comb, gint_trig_t trig, gint_cb_t callback)
  84. {
  85. uint32_t instance;
  86. instance = GINT_GetInstance(base);
  87. base->CTRL = (GINT_CTRL_COMB(comb) | GINT_CTRL_TRIG(trig));
  88. /* Save callback pointer */
  89. s_gintCallback[instance] = callback;
  90. }
  91. void GINT_GetCtrl(GINT_Type *base, gint_comb_t *comb, gint_trig_t *trig, gint_cb_t *callback)
  92. {
  93. uint32_t instance;
  94. instance = GINT_GetInstance(base);
  95. *comb = (gint_comb_t)((base->CTRL & GINT_CTRL_COMB_MASK) >> GINT_CTRL_COMB_SHIFT);
  96. *trig = (gint_trig_t)((base->CTRL & GINT_CTRL_TRIG_MASK) >> GINT_CTRL_TRIG_SHIFT);
  97. *callback = s_gintCallback[instance];
  98. }
  99. void GINT_ConfigPins(GINT_Type *base, gint_port_t port, uint32_t polarityMask, uint32_t enableMask)
  100. {
  101. base->PORT_POL[port] = polarityMask;
  102. base->PORT_ENA[port] = enableMask;
  103. }
  104. void GINT_GetConfigPins(GINT_Type *base, gint_port_t port, uint32_t *polarityMask, uint32_t *enableMask)
  105. {
  106. *polarityMask = base->PORT_POL[port];
  107. *enableMask = base->PORT_ENA[port];
  108. }
  109. void GINT_EnableCallback(GINT_Type *base)
  110. {
  111. uint32_t instance;
  112. instance = GINT_GetInstance(base);
  113. /* If GINT is configured in "AND" mode a spurious interrupt is generated.
  114. Clear status and pending interrupt before enabling the irq in NVIC. */
  115. GINT_ClrStatus(base);
  116. NVIC_ClearPendingIRQ(s_gintIRQ[instance]);
  117. EnableIRQ(s_gintIRQ[instance]);
  118. }
  119. void GINT_DisableCallback(GINT_Type *base)
  120. {
  121. uint32_t instance;
  122. instance = GINT_GetInstance(base);
  123. DisableIRQ(s_gintIRQ[instance]);
  124. GINT_ClrStatus(base);
  125. NVIC_ClearPendingIRQ(s_gintIRQ[instance]);
  126. }
  127. void GINT_Deinit(GINT_Type *base)
  128. {
  129. uint32_t instance;
  130. instance = GINT_GetInstance(base);
  131. /* Cleanup */
  132. GINT_DisableCallback(base);
  133. s_gintCallback[instance] = NULL;
  134. /* Reset the peripheral */
  135. RESET_PeripheralReset(s_gintResets[instance]);
  136. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  137. /* Disable the peripheral clock */
  138. CLOCK_DisableClock(s_gintClocks[instance]);
  139. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  140. }
  141. /* IRQ handler functions overloading weak symbols in the startup */
  142. #if defined(GINT0)
  143. void GINT0_DriverIRQHandler(void)
  144. {
  145. /* Clear interrupt before callback */
  146. s_gintBases[0]->CTRL |= GINT_CTRL_INT_MASK;
  147. /* Call user function */
  148. if (s_gintCallback[0] != NULL)
  149. {
  150. s_gintCallback[0]();
  151. }
  152. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  153. exception return operation might vector to incorrect interrupt */
  154. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  155. __DSB();
  156. #endif
  157. }
  158. #endif
  159. #if defined(GINT1)
  160. void GINT1_DriverIRQHandler(void)
  161. {
  162. /* Clear interrupt before callback */
  163. s_gintBases[1]->CTRL |= GINT_CTRL_INT_MASK;
  164. /* Call user function */
  165. if (s_gintCallback[1] != NULL)
  166. {
  167. s_gintCallback[1]();
  168. }
  169. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  170. exception return operation might vector to incorrect interrupt */
  171. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  172. __DSB();
  173. #endif
  174. }
  175. #endif
  176. #if defined(GINT2)
  177. void GINT2_DriverIRQHandler(void)
  178. {
  179. /* Clear interrupt before callback */
  180. s_gintBases[2]->CTRL |= GINT_CTRL_INT_MASK;
  181. /* Call user function */
  182. if (s_gintCallback[2] != NULL)
  183. {
  184. s_gintCallback[2]();
  185. }
  186. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  187. exception return operation might vector to incorrect interrupt */
  188. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  189. __DSB();
  190. #endif
  191. }
  192. #endif
  193. #if defined(GINT3)
  194. void GINT3_DriverIRQHandler(void)
  195. {
  196. /* Clear interrupt before callback */
  197. s_gintBases[3]->CTRL |= GINT_CTRL_INT_MASK;
  198. /* Call user function */
  199. if (s_gintCallback[3] != NULL)
  200. {
  201. s_gintCallback[3]();
  202. }
  203. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  204. exception return operation might vector to incorrect interrupt */
  205. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  206. __DSB();
  207. #endif
  208. }
  209. #endif
  210. #if defined(GINT4)
  211. void GINT4_DriverIRQHandler(void)
  212. {
  213. /* Clear interrupt before callback */
  214. s_gintBases[4]->CTRL |= GINT_CTRL_INT_MASK;
  215. /* Call user function */
  216. if (s_gintCallback[4] != NULL)
  217. {
  218. s_gintCallback[4]();
  219. }
  220. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  221. exception return operation might vector to incorrect interrupt */
  222. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  223. __DSB();
  224. #endif
  225. }
  226. #endif
  227. #if defined(GINT5)
  228. void GINT5_DriverIRQHandler(void)
  229. {
  230. /* Clear interrupt before callback */
  231. s_gintBases[5]->CTRL |= GINT_CTRL_INT_MASK;
  232. /* Call user function */
  233. if (s_gintCallback[5] != NULL)
  234. {
  235. s_gintCallback[5]();
  236. }
  237. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  238. exception return operation might vector to incorrect interrupt */
  239. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  240. __DSB();
  241. #endif
  242. }
  243. #endif
  244. #if defined(GINT6)
  245. void GINT6_DriverIRQHandler(void)
  246. {
  247. /* Clear interrupt before callback */
  248. s_gintBases[6]->CTRL |= GINT_CTRL_INT_MASK;
  249. /* Call user function */
  250. if (s_gintCallback[6] != NULL)
  251. {
  252. s_gintCallback[6]();
  253. }
  254. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  255. exception return operation might vector to incorrect interrupt */
  256. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  257. __DSB();
  258. #endif
  259. }
  260. #endif
  261. #if defined(GINT7)
  262. void GINT7_DriverIRQHandler(void)
  263. {
  264. /* Clear interrupt before callback */
  265. s_gintBases[7]->CTRL |= GINT_CTRL_INT_MASK;
  266. /* Call user function */
  267. if (s_gintCallback[7] != NULL)
  268. {
  269. s_gintCallback[7]();
  270. }
  271. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  272. exception return operation might vector to incorrect interrupt */
  273. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  274. __DSB();
  275. #endif
  276. }
  277. #endif