Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

217 linhas
6.6 KiB

  1. /*
  2. * This file is part of the libopencm3 project.
  3. *
  4. * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
  5. * Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
  6. * Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
  7. *
  8. * This library is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU Lesser General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public License
  19. * along with this library. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. /** @defgroup CM3_nvic_file NVIC
  22. *
  23. * @ingroup CM3_files
  24. *
  25. * @brief <b>libopencm3 Cortex Nested Vectored Interrupt Controller</b>
  26. *
  27. * @version 1.0.0
  28. *
  29. * @author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
  30. * @author @htmlonly &copy; @endhtmlonly 2012 Fergus Noble
  31. * <fergusnoble@gmail.com>
  32. *
  33. * @date 18 August 2012
  34. *
  35. * Cortex processors provide 14 cortex-defined interrupts (NMI, usage faults,
  36. * systicks etc.) and varying numbers of implementation defined interrupts
  37. * (typically peripherial interrupts and DMA).
  38. *
  39. * @see Cortex-M3 Devices Generic User Guide
  40. * @see STM32F10xxx Cortex-M3 programming manual
  41. *
  42. * LGPL License Terms @ref lgpl_license
  43. */
  44. /**@{*/
  45. #include <libopencm3/cm3/nvic.h>
  46. #include <libopencm3/cm3/scb.h>
  47. /*---------------------------------------------------------------------------*/
  48. /** @brief NVIC Enable Interrupt
  49. *
  50. * Enables a user interrupt.
  51. *
  52. * @param[in] irqn Unsigned int8. Interrupt number @ref CM3_nvic_defines_irqs
  53. */
  54. void nvic_enable_irq(uint8_t irqn)
  55. {
  56. NVIC_ISER(irqn / 32) = (1 << (irqn % 32));
  57. }
  58. /*---------------------------------------------------------------------------*/
  59. /** @brief NVIC Disable Interrupt
  60. *
  61. * Disables a user interrupt.
  62. *
  63. * @param[in] irqn Unsigned int8. Interrupt number @ref CM3_nvic_defines_irqs
  64. */
  65. void nvic_disable_irq(uint8_t irqn)
  66. {
  67. NVIC_ICER(irqn / 32) = (1 << (irqn % 32));
  68. }
  69. /*---------------------------------------------------------------------------*/
  70. /** @brief NVIC Return Pending Interrupt
  71. *
  72. * True if the interrupt has occurred and is waiting for service.
  73. *
  74. * @param[in] irqn Unsigned int8. Interrupt number @ref CM3_nvic_defines_irqs
  75. * @return Boolean. Interrupt pending.
  76. */
  77. uint8_t nvic_get_pending_irq(uint8_t irqn)
  78. {
  79. return NVIC_ISPR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0;
  80. }
  81. /*---------------------------------------------------------------------------*/
  82. /** @brief NVIC Set Pending Interrupt
  83. *
  84. * Force a user interrupt to a pending state. This has no effect if the
  85. * interrupt is already pending.
  86. *
  87. * @param[in] irqn Unsigned int8. Interrupt number @ref CM3_nvic_defines_irqs
  88. */
  89. void nvic_set_pending_irq(uint8_t irqn)
  90. {
  91. NVIC_ISPR(irqn / 32) = (1 << (irqn % 32));
  92. }
  93. /*---------------------------------------------------------------------------*/
  94. /** @brief NVIC Clear Pending Interrupt
  95. *
  96. * Force remove a user interrupt from a pending state. This has no effect if
  97. * the interrupt is actively being serviced.
  98. *
  99. * @param[in] irqn Unsigned int8. Interrupt number @ref CM3_nvic_defines_irqs
  100. */
  101. void nvic_clear_pending_irq(uint8_t irqn)
  102. {
  103. NVIC_ICPR(irqn / 32) = (1 << (irqn % 32));
  104. }
  105. /*---------------------------------------------------------------------------*/
  106. /** @brief NVIC Return Enabled Interrupt
  107. *
  108. * @param[in] irqn Unsigned int8. Interrupt number @ref CM3_nvic_defines_irqs
  109. * @return Boolean. Interrupt enabled.
  110. */
  111. uint8_t nvic_get_irq_enabled(uint8_t irqn)
  112. {
  113. return NVIC_ISER(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0;
  114. }
  115. #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
  116. /** @brief NVIC Set Interrupt Priority
  117. *
  118. * There are 16 priority levels only, given by the upper four bits of the
  119. * priority byte, as required by ARM standards. The priority levels are
  120. * interpreted according to the pre-emptive priority grouping set in the
  121. * SCB Application Interrupt and Reset Control Register (SCB_AIRCR), as done
  122. * in @ref scb_set_priority_grouping,
  123. * @param[in] irqn Interrupt number @ref CM3_nvic_defines_irqs
  124. * @param[in] priority Interrupt priority (0 ... 255 in steps of 16)
  125. */
  126. #else
  127. /** NVIC Set Interrupt Priority.
  128. *
  129. * There are 4 priority levels only, given by the upper two bits of the
  130. * priority byte, as required by ARM standards. No grouping available.
  131. *
  132. * @param[in] irqn Interrupt number @ref CM3_nvic_defines_irqs
  133. * @param[in] priority Interrupt priority (0 ... 255 in steps of 16)
  134. */
  135. #endif
  136. void nvic_set_priority(uint8_t irqn, uint8_t priority)
  137. {
  138. /* code from lpc43xx/nvic.c -- this is quite a hack and alludes to the
  139. * negative interrupt numbers assigned to the system interrupts. better
  140. * handling would mean signed integers. */
  141. if (irqn >= NVIC_IRQ_COUNT) {
  142. /* Cortex-M system interrupts */
  143. #if defined(__ARM_ARCH_6M__)
  144. /* ARM6M supports only 32bit word access to SHPR registers */
  145. irqn = (irqn & 0xF) - 4;
  146. uint8_t shift = (irqn & 0x3) << 3;
  147. uint8_t reg = irqn >> 2;
  148. SCB_SHPR32(reg) = ((SCB_SHPR32(reg) & ~(0xFFUL << shift)) |
  149. ((uint32_t) priority) << shift);
  150. #else
  151. SCB_SHPR((irqn & 0xF) - 4) = priority;
  152. #endif
  153. } else {
  154. /* Device specific interrupts */
  155. #if defined(__ARM_ARCH_6M__)
  156. /* ARM6M supports only 32bit word access to IPR registers */
  157. uint8_t shift = (irqn & 0x3) << 3;
  158. uint8_t reg = irqn >> 2;
  159. NVIC_IPR32(reg) = ((NVIC_IPR32(reg) & ~(0xFFUL << shift)) |
  160. ((uint32_t) priority) << shift);
  161. #else
  162. NVIC_IPR(irqn) = priority;
  163. #endif
  164. }
  165. }
  166. /* Those are defined only on CM3 or CM4 */
  167. #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
  168. /*---------------------------------------------------------------------------*/
  169. /** @brief NVIC Return Active Interrupt
  170. *
  171. * Interrupt has occurred and is currently being serviced.
  172. *
  173. * @param[in] irqn Unsigned int8. Interrupt number @ref CM3_nvic_defines_irqs
  174. * @return Boolean. Interrupt active.
  175. */
  176. uint8_t nvic_get_active_irq(uint8_t irqn)
  177. {
  178. return NVIC_IABR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0;
  179. }
  180. /*---------------------------------------------------------------------------*/
  181. /** @brief NVIC Software Trigger Interrupt
  182. *
  183. * Generate an interrupt from software. This has no effect for unprivileged
  184. * access unless the privilege level has been elevated through the System
  185. * Control Registers.
  186. *
  187. * @param[in] irqn Unsigned int16. Interrupt number (0 ... 239)
  188. */
  189. void nvic_generate_software_interrupt(uint16_t irqn)
  190. {
  191. if (irqn <= 239) {
  192. NVIC_STIR |= irqn;
  193. }
  194. }
  195. #endif
  196. /**@}*/