interrupt.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
  1. //*****************************************************************************
  2. //
  3. // interrupt.c - Driver for the NVIC Interrupt Controller.
  4. //
  5. // Copyright (c) 2005-2017 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions
  10. // are met:
  11. //
  12. // Redistributions of source code must retain the above copyright
  13. // notice, this list of conditions and the following disclaimer.
  14. //
  15. // Redistributions in binary form must reproduce the above copyright
  16. // notice, this list of conditions and the following disclaimer in the
  17. // documentation and/or other materials provided with the
  18. // distribution.
  19. //
  20. // Neither the name of Texas Instruments Incorporated nor the names of
  21. // its contributors may be used to endorse or promote products derived
  22. // from this software without specific prior written permission.
  23. //
  24. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  28. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  29. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  30. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  34. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. //
  36. //*****************************************************************************
  37. //*****************************************************************************
  38. //
  39. //! \addtogroup interrupt_api
  40. //! @{
  41. //
  42. //*****************************************************************************
  43. #include "types.h"
  44. #include <stdbool.h>
  45. #include <stdint.h>
  46. #include "inc/hw_nvic.h"
  47. #include "cpu.h"
  48. #include "debug.h"
  49. #include "interrupt.h"
  50. //*****************************************************************************
  51. //
  52. // This is a mapping between priority grouping encodings and the number of
  53. // preemption priority bits.
  54. //
  55. //*****************************************************************************
  56. static const uint32_t g_pui32Priority[] =
  57. {
  58. NVIC_APINT_PRIGROUP_0_8, NVIC_APINT_PRIGROUP_1_7, NVIC_APINT_PRIGROUP_2_6,
  59. NVIC_APINT_PRIGROUP_3_5, NVIC_APINT_PRIGROUP_4_4, NVIC_APINT_PRIGROUP_5_3,
  60. NVIC_APINT_PRIGROUP_6_2, NVIC_APINT_PRIGROUP_7_1
  61. };
  62. //*****************************************************************************
  63. //
  64. // This is a mapping between interrupt number and the register that contains
  65. // the priority encoding for that interrupt.
  66. //
  67. //*****************************************************************************
  68. static const uint32_t g_pui32Regs[] =
  69. {
  70. 0, NVIC_SYS_PRI1, NVIC_SYS_PRI2, NVIC_SYS_PRI3, NVIC_PRI0, NVIC_PRI1,
  71. NVIC_PRI2, NVIC_PRI3, NVIC_PRI4, NVIC_PRI5, NVIC_PRI6, NVIC_PRI7,
  72. NVIC_PRI8, NVIC_PRI9, NVIC_PRI10, NVIC_PRI11, NVIC_PRI12, NVIC_PRI13,
  73. NVIC_PRI14, NVIC_PRI15, NVIC_PRI16, NVIC_PRI17, NVIC_PRI18, NVIC_PRI19,
  74. NVIC_PRI20, NVIC_PRI21, NVIC_PRI22, NVIC_PRI23, NVIC_PRI24, NVIC_PRI25,
  75. NVIC_PRI26, NVIC_PRI27, NVIC_PRI28, NVIC_PRI29, NVIC_PRI30, NVIC_PRI31,
  76. NVIC_PRI32, NVIC_PRI33, NVIC_PRI34
  77. };
  78. //*****************************************************************************
  79. //
  80. // This is a mapping between interrupt number (for the peripheral interrupts
  81. // only) and the register that contains the interrupt enable for that
  82. // interrupt.
  83. //
  84. //*****************************************************************************
  85. static const uint32_t g_pui32EnRegs[] =
  86. {
  87. NVIC_EN0, NVIC_EN1, NVIC_EN2, NVIC_EN3, NVIC_EN4
  88. };
  89. //*****************************************************************************
  90. //
  91. // This is a mapping between interrupt number (for the peripheral interrupts
  92. // only) and the register that contains the interrupt disable for that
  93. // interrupt.
  94. //
  95. //*****************************************************************************
  96. static const uint32_t g_pui32Dii16Regs[] =
  97. {
  98. NVIC_DIS0, NVIC_DIS1, NVIC_DIS2, NVIC_DIS3, NVIC_DIS4
  99. };
  100. //*****************************************************************************
  101. //
  102. // This is a mapping between interrupt number (for the peripheral interrupts
  103. // only) and the register that contains the interrupt pend for that interrupt.
  104. //
  105. //*****************************************************************************
  106. static const uint32_t g_pui32PendRegs[] =
  107. {
  108. NVIC_PEND0, NVIC_PEND1, NVIC_PEND2, NVIC_PEND3, NVIC_PEND4
  109. };
  110. //*****************************************************************************
  111. //
  112. // This is a mapping between interrupt number (for the peripheral interrupts
  113. // only) and the register that contains the interrupt unpend for that
  114. // interrupt.
  115. //
  116. //*****************************************************************************
  117. static const uint32_t g_pui32UnpendRegs[] =
  118. {
  119. NVIC_UNPEND0, NVIC_UNPEND1, NVIC_UNPEND2, NVIC_UNPEND3, NVIC_UNPEND4
  120. };
  121. //*****************************************************************************
  122. //
  123. //! \internal
  124. //! The default interrupt handler.
  125. //!
  126. //! This is the default interrupt handler for all interrupts. It simply loops
  127. //! forever so that the system state is preserved for observation by a
  128. //! debugger. Since interrupts must be disabled before unregistering the
  129. //! corresponding handler, this should never be called during normal operation.
  130. //!
  131. //! \return None.
  132. //
  133. //*****************************************************************************
  134. static void
  135. _IntDefaultHandler(void)
  136. {
  137. //
  138. // Go into an infinite loop.
  139. //
  140. while (1)
  141. {
  142. }
  143. }
  144. //*****************************************************************************
  145. //
  146. // The processor vector table.
  147. //
  148. // This contains a list of the handlers for the various interrupt sources in
  149. // the system. The layout of this list is defined by the hardware; assertion
  150. // of an interrupt causes the processor to start executing directly at the
  151. // address given in the corresponding location in this list.
  152. //
  153. //*****************************************************************************
  154. //
  155. // Set the size of the vector table to the largest number of interrupts of
  156. // any device
  157. //
  158. #undef NUM_INTERRUPTS
  159. #define NUM_INTERRUPTS 155
  160. #if defined(__ICCARM__)
  161. #pragma data_alignment=1024
  162. static __no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) @ "VTABLE";
  163. #elif defined(sourcerygxx)
  164. static __attribute__((section(".cs3.region-head.ram")))
  165. void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__((aligned(1024)));
  166. #elif defined(__TI_ARM__) || defined(DOXYGEN)
  167. #pragma DATA_ALIGN(g_pfnRAMVectors, 1024)
  168. #pragma DATA_SECTION(g_pfnRAMVectors, ".vtable")
  169. void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void);
  170. #else
  171. static __attribute__((section("vtable")))
  172. void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__((aligned(1024)));
  173. #endif
  174. //*****************************************************************************
  175. //
  176. //! Enables the processor interrupt.
  177. //!
  178. //! This function allows the processor to respond to interrupts. This function
  179. //! does not affect the set of interrupts enabled in the interrupt controller;
  180. //! it just gates the single interrupt from the controller to the processor.
  181. //!
  182. //! \b Example: Enable interrupts to the processor.
  183. //!
  184. //! \verbatim
  185. //! //
  186. //! // Enable interrupts to the processor.
  187. //! //
  188. //! IntMasterEnable();
  189. //!
  190. //! \endverbatim
  191. //!
  192. //! \return Returns \b true if interrupts were disabled when the function was
  193. //! called or \b false if they were initially enabled.
  194. //
  195. //*****************************************************************************
  196. bool
  197. IntMasterEnable(void)
  198. {
  199. //
  200. // Enable processor interrupts.
  201. //
  202. return (CPUcpsie());
  203. }
  204. //*****************************************************************************
  205. //
  206. //! Disables the processor interrupt.
  207. //!
  208. //! This function prevents the processor from receiving interrupts. This
  209. //! function does not affect the set of interrupts enabled in the interrupt
  210. //! controller; it just gates the single interrupt from the controller to the
  211. //! processor.
  212. //!
  213. //! \note Previously, this function had no return value. As such, it was
  214. //! possible to include <tt>interrupt.h</tt> and call this function without
  215. //! having included <tt>types.h</tt>. Now that the return is a
  216. //! <tt>bool</tt>, a compiler error occurs in this case. The solution
  217. //! is to include <tt>types.h</tt> before including <tt>interrupt.h</tt>.
  218. //!
  219. //! \b Example: Disable interrupts to the processor.
  220. //!
  221. //! \verbatim
  222. //! //
  223. //! // Disable interrupts to the processor.
  224. //! //
  225. //! IntMasterDisable();
  226. //!
  227. //! \endverbatim
  228. //!
  229. //! \return Returns \b true if interrupts were already disabled when the
  230. //! function was called or \b false if they were initially enabled.
  231. //
  232. //*****************************************************************************
  233. bool
  234. IntMasterDisable(void)
  235. {
  236. //
  237. // Disable processor interrupts.
  238. //
  239. return (CPUcpsid());
  240. }
  241. //*****************************************************************************
  242. //
  243. //! Registers a function to be called when an interrupt occurs.
  244. //!
  245. //! \param ui32Interrupt specifies the interrupt in question.
  246. //! \param pfnHandler is a pointer to the function to be called.
  247. //!
  248. //! This function is used to specify the handler function to be called when the
  249. //! given interrupt is asserted to the processor. The \e ui32Interrupt
  250. //! parameter must be one of the valid \b INT_* values listed in Peripheral
  251. //! Driver Library User's Guide and defined in the inc/hw_ints.h header file.
  252. //! When the interrupt occurs, if it is enabled (via IntEnable()), the handler
  253. //! function is called in interrupt context. Because the handler function can
  254. //! preempt other code, care must be taken to protect memory or peripherals
  255. //! that are accessed by the handler and other non-handler code.
  256. //!
  257. //! \note The use of this function (directly or indirectly via a peripheral
  258. //! driver interrupt register function) moves the interrupt vector table from
  259. //! flash to SRAM. Therefore, care must be taken when linking the application
  260. //! to ensure that the SRAM vector table is located at the beginning of SRAM;
  261. //! otherwise the NVIC does not look in the correct portion of memory for the
  262. //! vector table (it requires the vector table be on a 1 kB memory alignment).
  263. //! Normally, the SRAM vector table is so placed via the use of linker scripts.
  264. //! See the discussion of compile-time versus run-time interrupt handler
  265. //! registration in the introduction to this chapter.
  266. //!
  267. //! \b Example: Set the UART 0 interrupt handler.
  268. //!
  269. //! \verbatim
  270. //!
  271. //! //
  272. //! // UART 0 interrupt handler.
  273. //! //
  274. //! void
  275. //! UART0Handler(void)
  276. //! {
  277. //! //
  278. //! // Handle interrupt.
  279. //! //
  280. //! }
  281. //!
  282. //! //
  283. //! // Set the UART 0 interrupt handler.
  284. //! //
  285. //! IntRegister(INT_UART0, UART0Handler);
  286. //!
  287. //! \endverbatim
  288. //!
  289. //! \return None.
  290. //
  291. //*****************************************************************************
  292. void
  293. IntRegister(uint32_t ui32Interrupt, void (*pfnHandler)(void))
  294. {
  295. uint32_t ui32Idx, ui32Value;
  296. //
  297. // Check the arguments.
  298. //
  299. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  300. //
  301. // Make sure that the RAM vector table is correctly aligned.
  302. //
  303. ASSERT(((uint32_t)g_pfnRAMVectors & 0x000003ff) == 0);
  304. //
  305. // See if the RAM vector table has been initialized.
  306. //
  307. if (HWREG(NVIC_VTABLE) != (uint32_t)g_pfnRAMVectors)
  308. {
  309. //
  310. // Copy the vector table from the beginning of FLASH to the RAM vector
  311. // table.
  312. //
  313. ui32Value = HWREG(NVIC_VTABLE);
  314. for (ui32Idx = 0; ui32Idx < NUM_INTERRUPTS; ui32Idx++)
  315. {
  316. g_pfnRAMVectors[ui32Idx] = (void (*)(void))HWREG((ui32Idx * 4) +
  317. ui32Value);
  318. }
  319. //
  320. // Point the NVIC at the RAM vector table.
  321. //
  322. HWREG(NVIC_VTABLE) = (uint32_t)g_pfnRAMVectors;
  323. }
  324. //
  325. // Save the interrupt handler.
  326. //
  327. g_pfnRAMVectors[ui32Interrupt] = pfnHandler;
  328. }
  329. //*****************************************************************************
  330. //
  331. //! Unregisters the function to be called when an interrupt occurs.
  332. //!
  333. //! \param ui32Interrupt specifies the interrupt in question.
  334. //!
  335. //! This function is used to indicate that no handler is called when the
  336. //! given interrupt is asserted to the processor. The \e ui32Interrupt
  337. //! parameter must be one of the valid \b INT_* values listed in Peripheral
  338. //! Driver Library User's Guide and defined in the inc/hw_ints.h header file.
  339. //! The interrupt source is automatically disabled (via IntDisable()) if
  340. //! necessary.
  341. //!
  342. //! \sa IntRegister() for important information about registering interrupt
  343. //! handlers.
  344. //!
  345. //! \b Example: Reset the UART 0 interrupt handler to the default handler.
  346. //!
  347. //! \verbatim
  348. //! //
  349. //! // Reset the UART 0 interrupt handler to the default handler.
  350. //! //
  351. //! IntUnregister(INT_UART0);
  352. //!
  353. //! \endverbatim
  354. //!
  355. //! \return None.
  356. //
  357. //*****************************************************************************
  358. void
  359. IntUnregister(uint32_t ui32Interrupt)
  360. {
  361. //
  362. // Check the arguments.
  363. //
  364. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  365. //
  366. // Reset the interrupt handler.
  367. //
  368. g_pfnRAMVectors[ui32Interrupt] = _IntDefaultHandler;
  369. }
  370. //*****************************************************************************
  371. //
  372. //! Sets the priority grouping of the interrupt controller.
  373. //!
  374. //! \param ui32Bits specifies the number of bits of preemptable priority.
  375. //!
  376. //! This function specifies the split between preemptable priority levels and
  377. //! sub-priority levels in the interrupt priority specification. Three bits are
  378. //! available for hardware interrupt prioritization and therefore priority
  379. //! grouping values of three through seven have the same effect.
  380. //!
  381. //! \b Example: Set the priority grouping for the interrupt controller.
  382. //!
  383. //! \verbatim
  384. //! //
  385. //! // Set the priority grouping for the interrupt controller to 2 bits.
  386. //! //
  387. //! IntPriorityGroupingSet(2);
  388. //!
  389. //! \endverbatim
  390. //!
  391. //! \return None.
  392. //
  393. //*****************************************************************************
  394. void
  395. IntPriorityGroupingSet(uint32_t ui32Bits)
  396. {
  397. //
  398. // Check the arguments.
  399. //
  400. ASSERT(ui32Bits < NUM_PRIORITY);
  401. //
  402. // Set the priority grouping.
  403. //
  404. HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | g_pui32Priority[ui32Bits];
  405. }
  406. //*****************************************************************************
  407. //
  408. //! Gets the priority grouping of the interrupt controller.
  409. //!
  410. //! This function returns the split between preemptable priority levels and
  411. //! sub-priority levels in the interrupt priority specification.
  412. //!
  413. //! \b Example: Get the priority grouping for the interrupt controller.
  414. //!
  415. //! \verbatim
  416. //! //
  417. //! // Get the priority grouping for the interrupt controller.
  418. //! //
  419. //! IntPriorityGroupingGet();
  420. //!
  421. //! \endverbatim
  422. //!
  423. //! \return The number of bits of preemptable priority.
  424. //
  425. //*****************************************************************************
  426. uint32_t
  427. IntPriorityGroupingGet(void)
  428. {
  429. uint32_t ui32Loop, ui32Value;
  430. //
  431. // Read the priority grouping.
  432. //
  433. ui32Value = HWREG(NVIC_APINT) & NVIC_APINT_PRIGROUP_M;
  434. //
  435. // Loop through the priority grouping values.
  436. //
  437. for (ui32Loop = 0; ui32Loop < NUM_PRIORITY; ui32Loop++)
  438. {
  439. //
  440. // Stop looping if this value matches.
  441. //
  442. if (ui32Value == g_pui32Priority[ui32Loop])
  443. {
  444. break;
  445. }
  446. }
  447. //
  448. // Return the number of priority bits.
  449. //
  450. return (ui32Loop);
  451. }
  452. //*****************************************************************************
  453. //
  454. //! Sets the priority of an interrupt.
  455. //!
  456. //! \param ui32Interrupt specifies the interrupt in question.
  457. //! \param ui8Priority specifies the priority of the interrupt.
  458. //!
  459. //! This function is used to set the priority of an interrupt. The
  460. //! \e ui32Interrupt parameter must be one of the valid \b INT_* values listed
  461. //! in Peripheral Driver Library User's Guide and defined in the inc/hw_ints.h
  462. //! header file. The \e ui8Priority parameter specifies the interrupts
  463. //! hardware priority level of the interrupt in the interrupt controller.
  464. //! When multiple interrupts are asserted simultaneously, the ones with the
  465. //! highest priority are processed before the lower priority interrupts.
  466. //! Smaller numbers correspond to higher interrupt priorities; priority 0 is
  467. //! the highest interrupt priority.
  468. //!
  469. //! \note The hardware priority mechanism only looks at the upper 3 bits of the
  470. //! priority level, so any prioritization must be performed in those bits. The
  471. //! remaining bits can be used to sub-prioritize the interrupt sources, and may
  472. //! be used by the hardware priority mechanism. This arrangement allows
  473. //! priorities to migrate to different NVIC implementations without changing the
  474. //! gross prioritization of the interrupts.
  475. //!
  476. //! \b Example: Set priorities for UART 0 and USB interrupts.
  477. //!
  478. //! \verbatim
  479. //! //
  480. //! // Set the UART 0 interrupt priority to the lowest priority.
  481. //! //
  482. //! IntPrioritySet(INT_UART0, 0xE0);
  483. //!
  484. //! //
  485. //! // Set the USB 0 interrupt priority to the highest priority.
  486. //! //
  487. //! IntPrioritySet(INT_USB0, 0);
  488. //!
  489. //! \endverbatim
  490. //!
  491. //! \return None.
  492. //
  493. //*****************************************************************************
  494. void
  495. IntPrioritySet(uint32_t ui32Interrupt, uint8_t ui8Priority)
  496. {
  497. uint32_t ui32Temp;
  498. //
  499. // Check the arguments.
  500. //
  501. ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS));
  502. //
  503. // Set the interrupt priority.
  504. //
  505. ui32Temp = HWREG(g_pui32Regs[ui32Interrupt >> 2]);
  506. ui32Temp &= ~(0xFF << (8 * (ui32Interrupt & 3)));
  507. ui32Temp |= ui8Priority << (8 * (ui32Interrupt & 3));
  508. HWREG(g_pui32Regs[ui32Interrupt >> 2]) = ui32Temp;
  509. }
  510. //*****************************************************************************
  511. //
  512. //! Gets the priority of an interrupt.
  513. //!
  514. //! \param ui32Interrupt specifies the interrupt in question.
  515. //!
  516. //! This function gets the priority of an interrupt. The \e ui32Interrupt
  517. //! parameter must be one of the valid \b INT_* values listed in Peripheral
  518. //! Driver Library User's Guide and defined in the inc/hw_ints.h header file.
  519. //! See IntPrioritySet() for a full definition of the priority value.
  520. //!
  521. //! \b Example: Get the current UART 0 interrupt priority.
  522. //!
  523. //! \verbatim
  524. //! //
  525. //! // Get the current UART 0 interrupt priority.
  526. //! //
  527. //! IntPriorityGet(INT_UART0);
  528. //!
  529. //! \endverbatim
  530. //!
  531. //! \return Returns the interrupt priority for the given interrupt.
  532. //
  533. //*****************************************************************************
  534. int32_t
  535. IntPriorityGet(uint32_t ui32Interrupt)
  536. {
  537. //
  538. // Check the arguments.
  539. //
  540. ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS));
  541. //
  542. // Return the interrupt priority.
  543. //
  544. return ((HWREG(g_pui32Regs[ui32Interrupt >> 2]) >>
  545. (8 * (ui32Interrupt & 3))) & 0xFF);
  546. }
  547. //*****************************************************************************
  548. //
  549. //! Enables an interrupt.
  550. //!
  551. //! \param ui32Interrupt specifies the interrupt to be enabled.
  552. //!
  553. //! The specified interrupt is enabled in the interrupt controller. The
  554. //! \e ui32Interrupt parameter must be one of the valid \b INT_* values listed
  555. //! in Peripheral Driver Library User's Guide and defined in the inc/hw_ints.h
  556. //! header file. Other enables for the interrupt (such as at the peripheral
  557. //! level) are unaffected by this function.
  558. //!
  559. //! \b Example: Enable the UART 0 interrupt.
  560. //!
  561. //! \verbatim
  562. //! //
  563. //! // Enable the UART 0 interrupt in the interrupt controller.
  564. //! //
  565. //! IntEnable(INT_UART0);
  566. //!
  567. //! \endverbatim
  568. //!
  569. //! \return None.
  570. //
  571. //*****************************************************************************
  572. void
  573. IntEnable(uint32_t ui32Interrupt)
  574. {
  575. //
  576. // Check the arguments.
  577. //
  578. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  579. //
  580. // Determine the interrupt to enable.
  581. //
  582. if (ui32Interrupt == FAULT_MPU)
  583. {
  584. //
  585. // Enable the MemManage interrupt.
  586. //
  587. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_MEM;
  588. }
  589. else if (ui32Interrupt == FAULT_BUS)
  590. {
  591. //
  592. // Enable the bus fault interrupt.
  593. //
  594. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_BUS;
  595. }
  596. else if (ui32Interrupt == FAULT_USAGE)
  597. {
  598. //
  599. // Enable the usage fault interrupt.
  600. //
  601. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_USAGE;
  602. }
  603. else if (ui32Interrupt == FAULT_SYSTICK)
  604. {
  605. //
  606. // Enable the System Tick interrupt.
  607. //
  608. HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN;
  609. }
  610. else if (ui32Interrupt >= 16)
  611. {
  612. //
  613. // Enable the general interrupt.
  614. //
  615. HWREG(g_pui32EnRegs[(ui32Interrupt - 16) / 32]) =
  616. 1 << ((ui32Interrupt - 16) & 31);
  617. }
  618. }
  619. //*****************************************************************************
  620. //
  621. //! Disables an interrupt.
  622. //!
  623. //! \param ui32Interrupt specifies the interrupt to be disabled.
  624. //!
  625. //! The specified interrupt is disabled in the interrupt controller. The
  626. //! \e ui32Interrupt parameter must be one of the valid \b INT_* values listed
  627. //! in interrupt.h. Other enables for the interrupt (such as at the peripheral
  628. //! level) are unaffected by this function.
  629. //!
  630. //! \b Example: Disable the UART 0 interrupt.
  631. //!
  632. //! \verbatim
  633. //! //
  634. //! // Disable the UART 0 interrupt in the interrupt controller.
  635. //! //
  636. //! IntDisable(INT_UART0);
  637. //!
  638. //! \endverbatim
  639. //!
  640. //! \return None.
  641. //
  642. //*****************************************************************************
  643. void
  644. IntDisable(uint32_t ui32Interrupt)
  645. {
  646. //
  647. // Check the arguments.
  648. //
  649. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  650. //
  651. // Determine the interrupt to disable.
  652. //
  653. if (ui32Interrupt == FAULT_MPU)
  654. {
  655. //
  656. // Disable the MemManage interrupt.
  657. //
  658. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_MEM);
  659. }
  660. else if (ui32Interrupt == FAULT_BUS)
  661. {
  662. //
  663. // Disable the bus fault interrupt.
  664. //
  665. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_BUS);
  666. }
  667. else if (ui32Interrupt == FAULT_USAGE)
  668. {
  669. //
  670. // Disable the usage fault interrupt.
  671. //
  672. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_USAGE);
  673. }
  674. else if (ui32Interrupt == FAULT_SYSTICK)
  675. {
  676. //
  677. // Disable the System Tick interrupt.
  678. //
  679. HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN);
  680. }
  681. else if (ui32Interrupt >= 16)
  682. {
  683. //
  684. // Disable the general interrupt.
  685. //
  686. HWREG(g_pui32Dii16Regs[(ui32Interrupt - 16) / 32]) =
  687. 1 << ((ui32Interrupt - 16) & 31);
  688. }
  689. }
  690. //*****************************************************************************
  691. //
  692. //! Returns if a peripheral interrupt is enabled.
  693. //!
  694. //! \param ui32Interrupt specifies the interrupt to check.
  695. //!
  696. //! This function checks if the specified interrupt is enabled in the interrupt
  697. //! controller. The \e ui32Interrupt parameter must be one of the valid
  698. //! \b INT_* values listed in interrupt.h.
  699. //!
  700. //! \b Example: Disable the UART 0 interrupt if it is enabled.
  701. //!
  702. //! \verbatim
  703. //! //
  704. //! // Disable the UART 0 interrupt if it is enabled.
  705. //! //
  706. //! if(IntIsEnabled(INT_UART0))
  707. //! {
  708. //! IntDisable(INT_UART0);
  709. //! }
  710. //! \endverbatim
  711. //!
  712. //! \return A non-zero value if the interrupt is enabled.
  713. //
  714. //*****************************************************************************
  715. uint32_t
  716. IntIsEnabled(uint32_t ui32Interrupt)
  717. {
  718. uint32_t ui32Ret;
  719. //
  720. // Check the arguments.
  721. //
  722. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  723. //
  724. // Initialize the return value.
  725. //
  726. ui32Ret = 0;
  727. //
  728. // Determine the interrupt to disable.
  729. //
  730. if (ui32Interrupt == FAULT_MPU)
  731. {
  732. //
  733. // Check the MemManage interrupt.
  734. //
  735. ui32Ret = HWREG(NVIC_SYS_HND_CTRL) & NVIC_SYS_HND_CTRL_MEM;
  736. }
  737. else if (ui32Interrupt == FAULT_BUS)
  738. {
  739. //
  740. // Check the bus fault interrupt.
  741. //
  742. ui32Ret = HWREG(NVIC_SYS_HND_CTRL) & NVIC_SYS_HND_CTRL_BUS;
  743. }
  744. else if (ui32Interrupt == FAULT_USAGE)
  745. {
  746. //
  747. // Check the usage fault interrupt.
  748. //
  749. ui32Ret = HWREG(NVIC_SYS_HND_CTRL) & NVIC_SYS_HND_CTRL_USAGE;
  750. }
  751. else if (ui32Interrupt == FAULT_SYSTICK)
  752. {
  753. //
  754. // Check the System Tick interrupt.
  755. //
  756. ui32Ret = HWREG(NVIC_ST_CTRL) & NVIC_ST_CTRL_INTEN;
  757. }
  758. else if (ui32Interrupt >= 16)
  759. {
  760. //
  761. // Check the general interrupt.
  762. //
  763. ui32Ret = HWREG(g_pui32EnRegs[(ui32Interrupt - 16) / 32]) &
  764. (1 << ((ui32Interrupt - 16) & 31));
  765. }
  766. return (ui32Ret);
  767. }
  768. //*****************************************************************************
  769. //
  770. //! Pends an interrupt.
  771. //!
  772. //! \param ui32Interrupt specifies the interrupt to be pended.
  773. //!
  774. //! The specified interrupt is pended in the interrupt controller. The
  775. //! \e ui32Interrupt parameter must be one of the valid \b INT_* values listed
  776. //! in interrupt.h. Pending an interrupt causes the interrupt controller to
  777. //! execute the corresponding interrupt handler at the next available time,
  778. //! based on the current interrupt state priorities. For example, if called by
  779. //! a higher priority interrupt handler, the specified interrupt handler is not
  780. //! called until after the current interrupt handler has completed execution.
  781. //! The interrupt must have been enabled for it to be called.
  782. //!
  783. //! \b Example: Pend a UART 0 interrupt.
  784. //!
  785. //! \verbatim
  786. //! //
  787. //! // Pend a UART 0 interrupt.
  788. //! //
  789. //! IntPendSet(INT_UART0);
  790. //! \endverbatim
  791. //!
  792. //! \return None.
  793. //
  794. //*****************************************************************************
  795. void
  796. IntPendSet(uint32_t ui32Interrupt)
  797. {
  798. //
  799. // Check the arguments.
  800. //
  801. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  802. //
  803. // Determine the interrupt to pend.
  804. //
  805. if (ui32Interrupt == FAULT_NMI)
  806. {
  807. //
  808. // Pend the NMI interrupt.
  809. //
  810. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_NMI_SET;
  811. }
  812. else if (ui32Interrupt == FAULT_PENDSV)
  813. {
  814. //
  815. // Pend the PendSV interrupt.
  816. //
  817. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PEND_SV;
  818. }
  819. else if (ui32Interrupt == FAULT_SYSTICK)
  820. {
  821. //
  822. // Pend the SysTick interrupt.
  823. //
  824. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTSET;
  825. }
  826. else if (ui32Interrupt >= 16)
  827. {
  828. //
  829. // Pend the general interrupt.
  830. //
  831. HWREG(g_pui32PendRegs[(ui32Interrupt - 16) / 32]) =
  832. 1 << ((ui32Interrupt - 16) & 31);
  833. }
  834. }
  835. //*****************************************************************************
  836. //
  837. //! Un-pends an interrupt.
  838. //!
  839. //! \param ui32Interrupt specifies the interrupt to be un-pended. The
  840. //! \e ui32Interrupt parameter must be one of the valid \b INT_* values listed
  841. //! in interrupt.h.
  842. //!
  843. //! The specified interrupt is un-pended in the interrupt controller. This
  844. //! causes any previously generated interrupts that have not been handled
  845. //! yet (due to higher priority interrupts or the interrupt not having been
  846. //! enabled yet) to be discarded.
  847. //!
  848. //! \b Example: Un-pend a UART 0 interrupt.
  849. //!
  850. //! \verbatim
  851. //! //
  852. //! // Un-pend a UART 0 interrupt.
  853. //! //
  854. //! IntPendClear(INT_UART0);
  855. //! \endverbatim
  856. //!
  857. //! \return None.
  858. //
  859. //*****************************************************************************
  860. void
  861. IntPendClear(uint32_t ui32Interrupt)
  862. {
  863. //
  864. // Check the arguments.
  865. //
  866. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  867. //
  868. // Determine the interrupt to unpend.
  869. //
  870. if (ui32Interrupt == FAULT_PENDSV)
  871. {
  872. //
  873. // Unpend the PendSV interrupt.
  874. //
  875. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_UNPEND_SV;
  876. }
  877. else if (ui32Interrupt == FAULT_SYSTICK)
  878. {
  879. //
  880. // Unpend the SysTick interrupt.
  881. //
  882. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTCLR;
  883. }
  884. else if (ui32Interrupt >= 16)
  885. {
  886. //
  887. // Unpend the general interrupt.
  888. //
  889. HWREG(g_pui32UnpendRegs[(ui32Interrupt - 16) / 32]) =
  890. 1 << ((ui32Interrupt - 16) & 31);
  891. }
  892. }
  893. //*****************************************************************************
  894. //
  895. //! Sets the priority masking level
  896. //!
  897. //! \param ui32PriorityMask is the priority level that is masked.
  898. //!
  899. //! This function sets the interrupt priority masking level so that all
  900. //! interrupts at the specified or lesser priority level are masked. Masking
  901. //! interrupts can be used to globally disable a set of interrupts with
  902. //! priority below a predetermined threshold. A value of 0 disables priority
  903. //! masking.
  904. //!
  905. //! Smaller numbers correspond to higher interrupt priorities. So for example
  906. //! a priority level mask of 4 allows interrupts of priority level 0-3,
  907. //! and interrupts with a numerical priority of 4 and greater are blocked.
  908. //!
  909. //! \note The hardware priority mechanism only looks at the upper 3 bits of the
  910. //! priority level, so any prioritization must be performed in those bits.
  911. //!
  912. //! \b Example: Mask of interrupt priorities greater than or equal to 0x80.
  913. //!
  914. //! \verbatim
  915. //! //
  916. //! // Mask of interrupt priorities greater than or equal to 0x80.
  917. //! //
  918. //! IntPriorityMaskSet(0x80);
  919. //! \endverbatim
  920. //!
  921. //! \return None.
  922. //
  923. //*****************************************************************************
  924. void
  925. IntPriorityMaskSet(uint32_t ui32PriorityMask)
  926. {
  927. //
  928. // Set the priority mask.
  929. //
  930. CPUbasepriSet(ui32PriorityMask);
  931. }
  932. //*****************************************************************************
  933. //
  934. //! Gets the priority masking level
  935. //!
  936. //! This function gets the current setting of the interrupt priority masking
  937. //! level. The value returned is the priority level such that all interrupts
  938. //! of that and lesser priority are masked. A value of 0 means that priority
  939. //! masking is disabled.
  940. //!
  941. //! Smaller numbers correspond to higher interrupt priorities. So for example
  942. //! a priority level mask of 4 allows interrupts of priority level 0-3,
  943. //! and interrupts with a numerical priority of 4 and greater are blocked.
  944. //!
  945. //! The hardware priority mechanism only looks at the upper 3 bits of the
  946. //! priority level, so any prioritization must be performed in those bits.
  947. //!
  948. //! \b Example: Get the current interrupt priority mask.
  949. //!
  950. //! \verbatim
  951. //! //
  952. //! // Get the current interrupt priority mask.
  953. //! //
  954. //! IntPriorityMaskGet();
  955. //! \endverbatim
  956. //!
  957. //! \return Returns the value of the interrupt priority level mask.
  958. //
  959. //*****************************************************************************
  960. uint32_t
  961. IntPriorityMaskGet(void)
  962. {
  963. //
  964. // Return the current priority mask.
  965. //
  966. return (CPUbasepriGet());
  967. }
  968. //*****************************************************************************
  969. //
  970. //! Triggers an interrupt.
  971. //!
  972. //! \param ui32Interrupt specifies the interrupt to be triggered.
  973. //!
  974. //! This function performs a software trigger of an interrupt. The
  975. //! \e ui32Interrupt parameter must be one of the valid \b INT_* values listed
  976. //! in interrupt.h. The interrupt controller behaves as if the corresponding
  977. //! interrupt line was asserted, and the interrupt is handled in the same
  978. //! manner (meaning that it must be enabled in order to be processed, and the
  979. //! processing is based on its priority with respect to other unhandled
  980. //! interrupts).
  981. //!
  982. //! \return None.
  983. //
  984. //*****************************************************************************
  985. void
  986. IntTrigger(uint32_t ui32Interrupt)
  987. {
  988. //
  989. // Check the arguments.
  990. //
  991. ASSERT((ui32Interrupt >= 16) && (ui32Interrupt < NUM_INTERRUPTS));
  992. //
  993. // Trigger this interrupt.
  994. //
  995. HWREG(NVIC_SW_TRIG) = ui32Interrupt - 16;
  996. }
  997. //*****************************************************************************
  998. //
  999. // Close the Doxygen group.
  1000. //! @}
  1001. //
  1002. //*****************************************************************************