fsl_pint.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. /*
  2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "fsl_pint.h"
  31. /*******************************************************************************
  32. * Variables
  33. ******************************************************************************/
  34. /*! @brief Irq number array */
  35. static const IRQn_Type s_pintIRQ[FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS] = PINT_IRQS;
  36. /*! @brief Callback function array for PINT(s). */
  37. static pint_cb_t s_pintCallback[FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS];
  38. /*******************************************************************************
  39. * Code
  40. ******************************************************************************/
  41. void PINT_Init(PINT_Type *base)
  42. {
  43. uint32_t i;
  44. uint32_t pmcfg;
  45. assert(base);
  46. pmcfg = 0;
  47. for (i = 0; i < FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS; i++)
  48. {
  49. s_pintCallback[i] = NULL;
  50. }
  51. /* Disable all bit slices */
  52. for (i = 0; i < PINT_PIN_INT_COUNT; i++)
  53. {
  54. pmcfg = pmcfg | (kPINT_PatternMatchNever << (PININT_BITSLICE_CFG_START + (i * 3U)));
  55. }
  56. /* Enable the peripheral clock */
  57. CLOCK_EnableClock(kCLOCK_Pint);
  58. /* Reset the peripheral */
  59. RESET_PeripheralReset(kPINT_RST_SHIFT_RSTn);
  60. /* Disable all pattern match bit slices */
  61. base->PMCFG = pmcfg;
  62. }
  63. void PINT_PinInterruptConfig(PINT_Type *base, pint_pin_int_t intr, pint_pin_enable_t enable, pint_cb_t callback)
  64. {
  65. assert(base);
  66. /* Clear Rise and Fall flags first */
  67. PINT_PinInterruptClrRiseFlag(base, intr);
  68. PINT_PinInterruptClrFallFlag(base, intr);
  69. /* select level or edge sensitive */
  70. base->ISEL = (base->ISEL & ~(1U << intr)) | ((enable & PINT_PIN_INT_LEVEL) ? (1U << intr) : 0U);
  71. /* enable rising or level interrupt */
  72. if (enable & (PINT_PIN_INT_LEVEL | PINT_PIN_INT_RISE))
  73. {
  74. base->SIENR = 1U << intr;
  75. }
  76. else
  77. {
  78. base->CIENR = 1U << intr;
  79. }
  80. /* Enable falling or select high level */
  81. if (enable & PINT_PIN_INT_FALL_OR_HIGH_LEVEL)
  82. {
  83. base->SIENF = 1U << intr;
  84. }
  85. else
  86. {
  87. base->CIENF = 1U << intr;
  88. }
  89. s_pintCallback[intr] = callback;
  90. }
  91. void PINT_PinInterruptGetConfig(PINT_Type *base, pint_pin_int_t pintr, pint_pin_enable_t *enable, pint_cb_t *callback)
  92. {
  93. uint32_t mask;
  94. bool level;
  95. assert(base);
  96. *enable = kPINT_PinIntEnableNone;
  97. level = false;
  98. mask = 1U << pintr;
  99. if (base->ISEL & mask)
  100. {
  101. /* Pin interrupt is level sensitive */
  102. level = true;
  103. }
  104. if (base->IENR & mask)
  105. {
  106. if (level)
  107. {
  108. /* Level interrupt is enabled */
  109. *enable = kPINT_PinIntEnableLowLevel;
  110. }
  111. else
  112. {
  113. /* Rising edge interrupt */
  114. *enable = kPINT_PinIntEnableRiseEdge;
  115. }
  116. }
  117. if (base->IENF & mask)
  118. {
  119. if (level)
  120. {
  121. /* Level interrupt is active high */
  122. *enable = kPINT_PinIntEnableHighLevel;
  123. }
  124. else
  125. {
  126. /* Either falling or both edge */
  127. if (*enable == kPINT_PinIntEnableRiseEdge)
  128. {
  129. /* Rising and faling edge */
  130. *enable = kPINT_PinIntEnableBothEdges;
  131. }
  132. else
  133. {
  134. /* Falling edge */
  135. *enable = kPINT_PinIntEnableFallEdge;
  136. }
  137. }
  138. }
  139. *callback = s_pintCallback[pintr];
  140. }
  141. void PINT_PatternMatchConfig(PINT_Type *base, pint_pmatch_bslice_t bslice, pint_pmatch_cfg_t *cfg)
  142. {
  143. uint32_t src_shift;
  144. uint32_t cfg_shift;
  145. uint32_t pmcfg;
  146. assert(base);
  147. src_shift = PININT_BITSLICE_SRC_START + (bslice * 3U);
  148. cfg_shift = PININT_BITSLICE_CFG_START + (bslice * 3U);
  149. /* Input source selection for selected bit slice */
  150. base->PMSRC = (base->PMSRC & ~(PININT_BITSLICE_SRC_MASK << src_shift)) | (cfg->bs_src << src_shift);
  151. /* Bit slice configuration */
  152. pmcfg = base->PMCFG;
  153. pmcfg = (pmcfg & ~(PININT_BITSLICE_CFG_MASK << cfg_shift)) | (cfg->bs_cfg << cfg_shift);
  154. /* If end point is true, enable the bits */
  155. if (bslice != 7U)
  156. {
  157. if (cfg->end_point)
  158. {
  159. pmcfg |= (0x1U << bslice);
  160. }
  161. else
  162. {
  163. pmcfg &= ~(0x1U << bslice);
  164. }
  165. }
  166. base->PMCFG = pmcfg;
  167. /* Save callback pointer */
  168. s_pintCallback[bslice] = cfg->callback;
  169. }
  170. void PINT_PatternMatchGetConfig(PINT_Type *base, pint_pmatch_bslice_t bslice, pint_pmatch_cfg_t *cfg)
  171. {
  172. uint32_t src_shift;
  173. uint32_t cfg_shift;
  174. assert(base);
  175. src_shift = PININT_BITSLICE_SRC_START + (bslice * 3U);
  176. cfg_shift = PININT_BITSLICE_CFG_START + (bslice * 3U);
  177. cfg->bs_src = (pint_pmatch_input_src_t)((base->PMSRC & (PININT_BITSLICE_SRC_MASK << src_shift)) >> src_shift);
  178. cfg->bs_cfg = (pint_pmatch_bslice_cfg_t)((base->PMCFG & (PININT_BITSLICE_CFG_MASK << cfg_shift)) >> cfg_shift);
  179. if (bslice == 7U)
  180. {
  181. cfg->end_point = true;
  182. }
  183. else
  184. {
  185. cfg->end_point = (base->PMCFG & (0x1U << bslice)) >> bslice;
  186. }
  187. cfg->callback = s_pintCallback[bslice];
  188. }
  189. uint32_t PINT_PatternMatchResetDetectLogic(PINT_Type *base)
  190. {
  191. uint32_t pmctrl;
  192. uint32_t pmstatus;
  193. uint32_t pmsrc;
  194. pmctrl = PINT->PMCTRL;
  195. pmstatus = pmctrl >> PINT_PMCTRL_PMAT_SHIFT;
  196. if (pmstatus)
  197. {
  198. /* Reset Pattern match engine detection logic */
  199. pmsrc = base->PMSRC;
  200. base->PMSRC = pmsrc;
  201. }
  202. return (pmstatus);
  203. }
  204. void PINT_EnableCallback(PINT_Type *base)
  205. {
  206. uint32_t i;
  207. assert(base);
  208. PINT_PinInterruptClrStatusAll(base);
  209. for (i = 0; i < FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS; i++)
  210. {
  211. NVIC_ClearPendingIRQ(s_pintIRQ[i]);
  212. PINT_PinInterruptClrStatus(base, (pint_pin_int_t)i);
  213. EnableIRQ(s_pintIRQ[i]);
  214. }
  215. }
  216. void PINT_DisableCallback(PINT_Type *base)
  217. {
  218. uint32_t i;
  219. assert(base);
  220. for (i = 0; i < FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS; i++)
  221. {
  222. DisableIRQ(s_pintIRQ[i]);
  223. PINT_PinInterruptClrStatus(base, (pint_pin_int_t)i);
  224. NVIC_ClearPendingIRQ(s_pintIRQ[i]);
  225. }
  226. }
  227. void PINT_Deinit(PINT_Type *base)
  228. {
  229. uint32_t i;
  230. assert(base);
  231. /* Cleanup */
  232. PINT_DisableCallback(base);
  233. for (i = 0; i < FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS; i++)
  234. {
  235. s_pintCallback[i] = NULL;
  236. }
  237. /* Reset the peripheral */
  238. RESET_PeripheralReset(kPINT_RST_SHIFT_RSTn);
  239. /* Disable the peripheral clock */
  240. CLOCK_DisableClock(kCLOCK_Pint);
  241. }
  242. /* IRQ handler functions overloading weak symbols in the startup */
  243. void PIN_INT0_DriverIRQHandler(void)
  244. {
  245. uint32_t pmstatus;
  246. /* Reset pattern match detection */
  247. pmstatus = PINT_PatternMatchResetDetectLogic(PINT);
  248. /* Clear Pin interrupt before callback */
  249. PINT_PinInterruptClrStatus(PINT, kPINT_PinInt0);
  250. /* Call user function */
  251. if (s_pintCallback[kPINT_PinInt0] != NULL)
  252. {
  253. s_pintCallback[kPINT_PinInt0](kPINT_PinInt0, pmstatus);
  254. }
  255. }
  256. #if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 1U)
  257. void PIN_INT1_DriverIRQHandler(void)
  258. {
  259. uint32_t pmstatus;
  260. /* Reset pattern match detection */
  261. pmstatus = PINT_PatternMatchResetDetectLogic(PINT);
  262. /* Clear Pin interrupt before callback */
  263. PINT_PinInterruptClrStatus(PINT, kPINT_PinInt1);
  264. /* Call user function */
  265. if (s_pintCallback[kPINT_PinInt1] != NULL)
  266. {
  267. s_pintCallback[kPINT_PinInt1](kPINT_PinInt1, pmstatus);
  268. }
  269. }
  270. #endif
  271. #if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 2U)
  272. void PIN_INT2_DriverIRQHandler(void)
  273. {
  274. uint32_t pmstatus;
  275. /* Reset pattern match detection */
  276. pmstatus = PINT_PatternMatchResetDetectLogic(PINT);
  277. /* Clear Pin interrupt before callback */
  278. PINT_PinInterruptClrStatus(PINT, kPINT_PinInt2);
  279. /* Call user function */
  280. if (s_pintCallback[kPINT_PinInt2] != NULL)
  281. {
  282. s_pintCallback[kPINT_PinInt2](kPINT_PinInt2, pmstatus);
  283. }
  284. }
  285. #endif
  286. #if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 3U)
  287. void PIN_INT3_DriverIRQHandler(void)
  288. {
  289. uint32_t pmstatus;
  290. /* Reset pattern match detection */
  291. pmstatus = PINT_PatternMatchResetDetectLogic(PINT);
  292. /* Clear Pin interrupt before callback */
  293. PINT_PinInterruptClrStatus(PINT, kPINT_PinInt3);
  294. /* Call user function */
  295. if (s_pintCallback[kPINT_PinInt3] != NULL)
  296. {
  297. s_pintCallback[kPINT_PinInt3](kPINT_PinInt3, pmstatus);
  298. }
  299. }
  300. #endif
  301. #if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 4U)
  302. void PIN_INT4_DriverIRQHandler(void)
  303. {
  304. uint32_t pmstatus;
  305. /* Reset pattern match detection */
  306. pmstatus = PINT_PatternMatchResetDetectLogic(PINT);
  307. /* Clear Pin interrupt before callback */
  308. PINT_PinInterruptClrStatus(PINT, kPINT_PinInt4);
  309. /* Call user function */
  310. if (s_pintCallback[kPINT_PinInt4] != NULL)
  311. {
  312. s_pintCallback[kPINT_PinInt4](kPINT_PinInt4, pmstatus);
  313. }
  314. }
  315. #endif
  316. #if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 5U)
  317. void PIN_INT5_DriverIRQHandler(void)
  318. {
  319. uint32_t pmstatus;
  320. /* Reset pattern match detection */
  321. pmstatus = PINT_PatternMatchResetDetectLogic(PINT);
  322. /* Clear Pin interrupt before callback */
  323. PINT_PinInterruptClrStatus(PINT, kPINT_PinInt5);
  324. /* Call user function */
  325. if (s_pintCallback[kPINT_PinInt5] != NULL)
  326. {
  327. s_pintCallback[kPINT_PinInt5](kPINT_PinInt5, pmstatus);
  328. }
  329. }
  330. #endif
  331. #if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 6U)
  332. void PIN_INT6_DriverIRQHandler(void)
  333. {
  334. uint32_t pmstatus;
  335. /* Reset pattern match detection */
  336. pmstatus = PINT_PatternMatchResetDetectLogic(PINT);
  337. /* Clear Pin interrupt before callback */
  338. PINT_PinInterruptClrStatus(PINT, kPINT_PinInt6);
  339. /* Call user function */
  340. if (s_pintCallback[kPINT_PinInt6] != NULL)
  341. {
  342. s_pintCallback[kPINT_PinInt6](kPINT_PinInt6, pmstatus);
  343. }
  344. }
  345. #endif
  346. #if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 7U)
  347. void PIN_INT7_DriverIRQHandler(void)
  348. {
  349. uint32_t pmstatus;
  350. /* Reset pattern match detection */
  351. pmstatus = PINT_PatternMatchResetDetectLogic(PINT);
  352. /* Clear Pin interrupt before callback */
  353. PINT_PinInterruptClrStatus(PINT, kPINT_PinInt7);
  354. /* Call user function */
  355. if (s_pintCallback[kPINT_PinInt7] != NULL)
  356. {
  357. s_pintCallback[kPINT_PinInt7](kPINT_PinInt7, pmstatus);
  358. }
  359. }
  360. #endif