sama_aic.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. /**
  14. * @file SAMA5D2x/aic.c
  15. * @brief SAMA AIC support code.
  16. *
  17. * @addtogroup SAMA5D2x_AIC
  18. * @{
  19. */
  20. #include "hal.h"
  21. /*===========================================================================*/
  22. /* Driver local definitions. */
  23. /*===========================================================================*/
  24. /*===========================================================================*/
  25. /* Driver exported variables. */
  26. /*===========================================================================*/
  27. /*===========================================================================*/
  28. /* Driver local types. */
  29. /*===========================================================================*/
  30. /*===========================================================================*/
  31. /* Driver local variables. */
  32. /*===========================================================================*/
  33. /*===========================================================================*/
  34. /* Driver local functions. */
  35. /*===========================================================================*/
  36. /*===========================================================================*/
  37. /* Driver local macros. */
  38. /*===========================================================================*/
  39. /**
  40. * @brief Enable write protection on AIC registers block.
  41. *
  42. * @param[in] aicp pointer to a AIC register block
  43. *
  44. * @notapi
  45. */
  46. #define aicEnableWP(aicp) { \
  47. aicp->AIC_WPMR = AIC_WPMR_WPKEY_PASSWD | AIC_WPMR_WPEN; \
  48. }
  49. /**
  50. * @brief Disable write protection on AIC registers block.
  51. *
  52. * @param[in] aicp pointer to a AIC register block
  53. *
  54. * @notapi
  55. */
  56. #define aicDisableWP(aicp) { \
  57. aicp->AIC_WPMR = AIC_WPMR_WPKEY_PASSWD; \
  58. }
  59. /**
  60. * @brief Checks if a IRQ priority is within the valid range.
  61. * @param[in] prio IRQ priority
  62. *
  63. * @retval The check result.
  64. * @retval FALSE invalid IRQ priority.
  65. * @retval TRUE correct IRQ priority.
  66. */
  67. #define SAMA_IRQ_IS_VALID_PRIORITY(prio) ((prio) <= 7U)
  68. /*===========================================================================*/
  69. /* Driver exported functions. */
  70. /*===========================================================================*/
  71. static OSAL_IRQ_HANDLER(aicSpuriousHandler) {
  72. OSAL_IRQ_PROLOGUE();
  73. osalSysHalt("Spurious interrupt");
  74. OSAL_IRQ_EPILOGUE();
  75. }
  76. static OSAL_IRQ_HANDLER(aicUnexpectedHandler) {
  77. OSAL_IRQ_PROLOGUE();
  78. osalSysHalt("Unexpected interrupt");
  79. OSAL_IRQ_EPILOGUE();
  80. }
  81. /**
  82. * @brief AIC Initialization.
  83. * @note Better reset everything in the AIC.
  84. *
  85. * @notapi
  86. */
  87. void aicInit(void) {
  88. #if SAMA_HAL_IS_SECURE
  89. Aic *aic = SAIC;
  90. #else
  91. Aic *aic = AIC;
  92. #endif
  93. aicDisableWP(aic);
  94. aic->AIC_SPU = (uint32_t)aicSpuriousHandler;
  95. aic->AIC_SSR = 0;
  96. aic->AIC_SVR = (uint32_t)aicUnexpectedHandler;
  97. unsigned i;
  98. /* Disable all interrupts */
  99. for (i = 1; i < ID_PERIPH_COUNT; i++) {
  100. aic->AIC_SSR = i;
  101. aic->AIC_IDCR = AIC_IDCR_INTD;
  102. /* Changes type */
  103. aic->AIC_SMR = AIC_SMR_SRCTYPE(EXT_NEGATIVE_EDGE);
  104. /* Clear pending interrupt */
  105. aic->AIC_ICCR = AIC_ICCR_INTCLR;
  106. /* Changes type */
  107. aic->AIC_SMR = AIC_SMR_SRCTYPE(INT_LEVEL_SENSITIVE);
  108. /* Default handler */
  109. aic->AIC_SVR = (uint32_t)aicUnexpectedHandler;
  110. }
  111. aicEnableWP(aic);
  112. }
  113. /**
  114. * @brief Configures an interrupt in the AIC.
  115. * @note Source cannot be ID_SAIC_FIQ (0).
  116. *
  117. * @param[in] source interrupt source to configure
  118. * @param[in] priority priority level of the selected source.
  119. */
  120. void aicSetSourcePriority(uint32_t source, uint8_t priority) {
  121. #if SAMA_HAL_IS_SECURE
  122. Aic *aic = SAIC;
  123. #else
  124. Aic *aic = AIC;
  125. #endif
  126. osalDbgCheck(source != ID_SAIC_FIQ);
  127. osalDbgAssert(SAMA_IRQ_IS_VALID_PRIORITY(priority), "invalid irq priority");
  128. /* Disable write protection */
  129. aicDisableWP(aic);
  130. /* Set source id */
  131. aic->AIC_SSR = source;
  132. /* Disable the interrupt first */
  133. aic->AIC_IDCR = AIC_IDCR_INTD;
  134. /* Configure priority */
  135. aic->AIC_SMR |= AIC_SMR_PRIOR(priority);
  136. /* Clear interrupt */
  137. aic->AIC_ICCR = AIC_ICCR_INTCLR;
  138. /* Enable write protection */
  139. aicEnableWP(aic);
  140. }
  141. /**
  142. * @brief Configures type of interrupt in the AIC.
  143. *
  144. * @param[in] source interrupt source to configure
  145. * @param[in] type type interrupt of the selected source.
  146. */
  147. void aicSetIntSourceType(uint32_t source, uint8_t type) {
  148. #if SAMA_HAL_IS_SECURE
  149. Aic *aic = SAIC;
  150. #else
  151. Aic *aic = AIC;
  152. #endif
  153. /* Disable write protection */
  154. aicDisableWP(aic);
  155. /* Set source id */
  156. aic->AIC_SSR = source;
  157. /* Disable the interrupt first */
  158. aic->AIC_IDCR = AIC_IDCR_INTD;
  159. /* Configure priority */
  160. aic->AIC_SMR |= AIC_SMR_SRCTYPE(type);
  161. /* Clear interrupt */
  162. aic->AIC_ICCR = AIC_ICCR_INTCLR;
  163. /* Enable write protection */
  164. aicEnableWP(aic);
  165. }
  166. /**
  167. * @brief Sets the source handler of an interrupt.
  168. *
  169. * @param[in] source interrupt source to configure
  170. * @param[in] handler handler for the interrupt source selected
  171. */
  172. void aicSetSourceHandler(uint32_t source, bool (*handler)(void)) {
  173. #if SAMA_HAL_IS_SECURE
  174. Aic *aic = SAIC;
  175. #else
  176. Aic *aic = AIC;
  177. #endif
  178. /* Disable write protection */
  179. aicDisableWP(aic);
  180. /* Select source and assign handler */
  181. aic->AIC_SSR = AIC_SSR_INTSEL(source);
  182. aic->AIC_SVR = (uint32_t)handler;
  183. /* Enable write protection */
  184. aicEnableWP(aic);
  185. }
  186. /**
  187. * @brief Sets the spurious handler of an interrupt.
  188. *
  189. * @param[in] handler handler for the interrupt
  190. */
  191. void aicSetSpuriousHandler(bool (*handler)(void)) {
  192. #if SAMA_HAL_IS_SECURE
  193. Aic *aic = SAIC;
  194. #else
  195. Aic *aic = AIC;
  196. #endif
  197. /* Disable write protection */
  198. aicDisableWP(aic);
  199. /* Assign handler */
  200. aic->AIC_SPU = (uint32_t)handler;
  201. /* Enable write protection */
  202. aicEnableWP(aic);
  203. }
  204. /**
  205. * @brief Enables interrupts coming from the source.
  206. *
  207. * @param[in] source interrupt source to enable
  208. */
  209. void aicEnableInt(uint32_t source) {
  210. #if SAMA_HAL_IS_SECURE
  211. Aic *aic = SAIC;
  212. #else
  213. Aic *aic = AIC;
  214. #endif
  215. aic->AIC_SSR = AIC_SSR_INTSEL(source);
  216. aic->AIC_IECR = AIC_IECR_INTEN;
  217. }
  218. /**
  219. * @brief Disables interrupts coming from the selected source.
  220. *
  221. * @param[in] source interrupt source to disable
  222. */
  223. void aicDisableInt(uint32_t source) {
  224. #if SAMA_HAL_IS_SECURE
  225. Aic *aic = SAIC;
  226. #else
  227. Aic *aic = AIC;
  228. #endif
  229. aic->AIC_SSR = AIC_SSR_INTSEL(source);
  230. aic->AIC_IDCR = AIC_IDCR_INTD;
  231. }
  232. /**
  233. * @brief Clears interrupts coming from the selected source.
  234. *
  235. * @param[in] source interrupt source to Clear
  236. */
  237. void aicClearInt(uint32_t source) {
  238. #if SAMA_HAL_IS_SECURE
  239. Aic *aic = SAIC;
  240. #else
  241. Aic *aic = AIC;
  242. #endif
  243. aic->AIC_SSR = AIC_SSR_INTSEL(source);
  244. aic->AIC_ICCR = AIC_ICCR_INTCLR;
  245. }
  246. /**
  247. * @brief Sets interrupts coming from the selected source.
  248. *
  249. * @param[in] source interrupt source to Set
  250. */
  251. void aicSetInt(uint32_t source) {
  252. #if SAMA_HAL_IS_SECURE
  253. Aic *aic = SAIC;
  254. #else
  255. Aic *aic = AIC;
  256. #endif
  257. aic->AIC_SSR = AIC_SSR_INTSEL(source);
  258. aic->AIC_ISCR = AIC_ISCR_INTSET;
  259. }
  260. /** @} */