interrupt.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. //*****************************************************************************
  2. //
  3. // interrupt.c - Driver for the NVIC Interrupt Controller.
  4. //
  5. // Copyright (c) 2005-2011 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of revision 8264 of the Stellaris Peripheral Driver Library.
  22. //
  23. //*****************************************************************************
  24. //*****************************************************************************
  25. //
  26. //! \addtogroup interrupt_api
  27. //! @{
  28. //
  29. //*****************************************************************************
  30. #include "inc/hw_ints.h"
  31. #include "inc/hw_nvic.h"
  32. #include "inc/hw_types.h"
  33. #include "driverlib/cpu.h"
  34. #include "driverlib/debug.h"
  35. #include "driverlib/interrupt.h"
  36. //*****************************************************************************
  37. //
  38. // This is a mapping between priority grouping encodings and the number of
  39. // preemption priority bits.
  40. //
  41. //*****************************************************************************
  42. static const unsigned long g_pulPriority[] =
  43. {
  44. NVIC_APINT_PRIGROUP_0_8, NVIC_APINT_PRIGROUP_1_7, NVIC_APINT_PRIGROUP_2_6,
  45. NVIC_APINT_PRIGROUP_3_5, NVIC_APINT_PRIGROUP_4_4, NVIC_APINT_PRIGROUP_5_3,
  46. NVIC_APINT_PRIGROUP_6_2, NVIC_APINT_PRIGROUP_7_1
  47. };
  48. //*****************************************************************************
  49. //
  50. // This is a mapping between interrupt number and the register that contains
  51. // the priority encoding for that interrupt.
  52. //
  53. //*****************************************************************************
  54. static const unsigned long g_pulRegs[] =
  55. {
  56. 0, NVIC_SYS_PRI1, NVIC_SYS_PRI2, NVIC_SYS_PRI3, NVIC_PRI0, NVIC_PRI1,
  57. NVIC_PRI2, NVIC_PRI3, NVIC_PRI4, NVIC_PRI5, NVIC_PRI6, NVIC_PRI7,
  58. NVIC_PRI8, NVIC_PRI9, NVIC_PRI10, NVIC_PRI11, NVIC_PRI12, NVIC_PRI13,
  59. NVIC_PRI14, NVIC_PRI15, NVIC_PRI16, NVIC_PRI17, NVIC_PRI18, NVIC_PRI19,
  60. NVIC_PRI20, NVIC_PRI21, NVIC_PRI22, NVIC_PRI23, NVIC_PRI24, NVIC_PRI25,
  61. NVIC_PRI26, NVIC_PRI27, NVIC_PRI28, NVIC_PRI29, NVIC_PRI30, NVIC_PRI31,
  62. NVIC_PRI32
  63. };
  64. //*****************************************************************************
  65. //
  66. // This is a mapping between interrupt number (for the peripheral interrupts
  67. // only) and the register that contains the interrupt enable for that
  68. // interrupt.
  69. //
  70. //*****************************************************************************
  71. static const unsigned long g_pulEnRegs[] =
  72. {
  73. NVIC_EN0, NVIC_EN1, NVIC_EN2, NVIC_EN3, NVIC_EN4
  74. };
  75. //*****************************************************************************
  76. //
  77. // This is a mapping between interrupt number (for the peripheral interrupts
  78. // only) and the register that contains the interrupt disable for that
  79. // interrupt.
  80. //
  81. //*****************************************************************************
  82. static const unsigned long g_pulDisRegs[] =
  83. {
  84. NVIC_DIS0, NVIC_DIS1, NVIC_DIS2, NVIC_DIS3, NVIC_DIS4
  85. };
  86. //*****************************************************************************
  87. //
  88. // This is a mapping between interrupt number (for the peripheral interrupts
  89. // only) and the register that contains the interrupt pend for that interrupt.
  90. //
  91. //*****************************************************************************
  92. static const unsigned long g_pulPendRegs[] =
  93. {
  94. NVIC_PEND0, NVIC_PEND1, NVIC_PEND2, NVIC_PEND3, NVIC_PEND4
  95. };
  96. //*****************************************************************************
  97. //
  98. // This is a mapping between interrupt number (for the peripheral interrupts
  99. // only) and the register that contains the interrupt unpend for that
  100. // interrupt.
  101. //
  102. //*****************************************************************************
  103. static const unsigned long g_pulUnpendRegs[] =
  104. {
  105. NVIC_UNPEND0, NVIC_UNPEND1, NVIC_UNPEND2, NVIC_UNPEND3, NVIC_UNPEND4
  106. };
  107. //*****************************************************************************
  108. //
  109. //! \internal
  110. //! The default interrupt handler.
  111. //!
  112. //! This is the default interrupt handler for all interrupts. It simply loops
  113. //! forever so that the system state is preserved for observation by a
  114. //! debugger. Since interrupts should be disabled before unregistering the
  115. //! corresponding handler, this should never be called.
  116. //!
  117. //! \return None.
  118. //
  119. //*****************************************************************************
  120. static void
  121. IntDefaultHandler(void)
  122. {
  123. //
  124. // Go into an infinite loop.
  125. //
  126. while(1)
  127. {
  128. }
  129. }
  130. //*****************************************************************************
  131. //
  132. // The processor vector table.
  133. //
  134. // This contains a list of the handlers for the various interrupt sources in
  135. // the system. The layout of this list is defined by the hardware; assertion
  136. // of an interrupt causes the processor to start executing directly at the
  137. // address given in the corresponding location in this list.
  138. //
  139. //*****************************************************************************
  140. #if defined(ewarm)
  141. #pragma data_alignment=1024
  142. static __no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) @ "VTABLE";
  143. #elif defined(sourcerygxx)
  144. static __attribute__((section(".cs3.region-head.ram")))
  145. void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__ ((aligned(1024)));
  146. #elif defined(ccs) || defined(DOXYGEN)
  147. #pragma DATA_ALIGN(g_pfnRAMVectors, 1024)
  148. #pragma DATA_SECTION(g_pfnRAMVectors, ".vtable")
  149. void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void);
  150. #else
  151. static __attribute__((section("vtable")))
  152. void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__ ((aligned(1024)));
  153. #endif
  154. //*****************************************************************************
  155. //
  156. //! Enables the processor interrupt.
  157. //!
  158. //! This function allows the processor to respond to interrupts. This function
  159. //! does not affect the set of interrupts enabled in the interrupt controller;
  160. //! it just gates the single interrupt from the controller to the processor.
  161. //!
  162. //! \note Previously, this function had no return value. As such, it was
  163. //! possible to include <tt>interrupt.h</tt> and call this function without
  164. //! having included <tt>hw_types.h</tt>. Now that the return is a
  165. //! <tt>tBoolean</tt>, a compiler error occurs in this case. The solution
  166. //! is to include <tt>hw_types.h</tt> before including <tt>interrupt.h</tt>.
  167. //!
  168. //! \return Returns \b true if interrupts were disabled when the function was
  169. //! called or \b false if they were initially enabled.
  170. //
  171. //*****************************************************************************
  172. tBoolean
  173. IntMasterEnable(void)
  174. {
  175. //
  176. // Enable processor interrupts.
  177. //
  178. return(CPUcpsie());
  179. }
  180. //*****************************************************************************
  181. //
  182. //! Disables the processor interrupt.
  183. //!
  184. //! This function prevents the processor from receiving interrupts. This
  185. //! function does not affect the set of interrupts enabled in the interrupt
  186. //! controller; it just gates the single interrupt from the controller to the
  187. //! processor.
  188. //!
  189. //! \note Previously, this function had no return value. As such, it was
  190. //! possible to include <tt>interrupt.h</tt> and call this function without
  191. //! having included <tt>hw_types.h</tt>. Now that the return is a
  192. //! <tt>tBoolean</tt>, a compiler error occurs in this case. The solution
  193. //! is to include <tt>hw_types.h</tt> before including <tt>interrupt.h</tt>.
  194. //!
  195. //! \return Returns \b true if interrupts were already disabled when the
  196. //! function was called or \b false if they were initially enabled.
  197. //
  198. //*****************************************************************************
  199. tBoolean
  200. IntMasterDisable(void)
  201. {
  202. //
  203. // Disable processor interrupts.
  204. //
  205. return(CPUcpsid());
  206. }
  207. //*****************************************************************************
  208. //
  209. //! Registers a function to be called when an interrupt occurs.
  210. //!
  211. //! \param ulInterrupt specifies the interrupt in question.
  212. //! \param pfnHandler is a pointer to the function to be called.
  213. //!
  214. //! This function is used to specify the handler function to be called when the
  215. //! given interrupt is asserted to the processor. When the interrupt occurs,
  216. //! if it is enabled (via IntEnable()), the handler function is called in
  217. //! interrupt context. Because the handler function can preempt other code,
  218. //! care must be taken to protect memory or peripherals that are accessed by
  219. //! the handler and other non-handler code.
  220. //!
  221. //! \note The use of this function (directly or indirectly via a peripheral
  222. //! driver interrupt register function) moves the interrupt vector table from
  223. //! flash to SRAM. Therefore, care must be taken when linking the application
  224. //! to ensure that the SRAM vector table is located at the beginning of SRAM;
  225. //! otherwise the NVIC does not look in the correct portion of memory for the
  226. //! vector table (it requires the vector table be on a 1 kB memory alignment).
  227. //! Normally, the SRAM vector table is so placed via the use of linker scripts.
  228. //! See the discussion of compile-time versus run-time interrupt handler
  229. //! registration in the introduction to this chapter.
  230. //!
  231. //! \return None.
  232. //
  233. //*****************************************************************************
  234. void
  235. IntRegister(unsigned long ulInterrupt, void (*pfnHandler)(void))
  236. {
  237. unsigned long ulIdx, ulValue;
  238. //
  239. // Check the arguments.
  240. //
  241. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  242. //
  243. // Make sure that the RAM vector table is correctly aligned.
  244. //
  245. ASSERT(((unsigned long)g_pfnRAMVectors & 0x000003ff) == 0);
  246. //
  247. // See if the RAM vector table has been initialized.
  248. //
  249. if(HWREG(NVIC_VTABLE) != (unsigned long)g_pfnRAMVectors)
  250. {
  251. //
  252. // Copy the vector table from the beginning of FLASH to the RAM vector
  253. // table.
  254. //
  255. ulValue = HWREG(NVIC_VTABLE);
  256. for(ulIdx = 0; ulIdx < NUM_INTERRUPTS; ulIdx++)
  257. {
  258. g_pfnRAMVectors[ulIdx] = (void (*)(void))HWREG((ulIdx * 4) +
  259. ulValue);
  260. }
  261. //
  262. // Point the NVIC at the RAM vector table.
  263. //
  264. HWREG(NVIC_VTABLE) = (unsigned long)g_pfnRAMVectors;
  265. }
  266. //
  267. // Save the interrupt handler.
  268. //
  269. g_pfnRAMVectors[ulInterrupt] = pfnHandler;
  270. }
  271. //*****************************************************************************
  272. //
  273. //! Unregisters the function to be called when an interrupt occurs.
  274. //!
  275. //! \param ulInterrupt specifies the interrupt in question.
  276. //!
  277. //! This function is used to indicate that no handler should be called when the
  278. //! given interrupt is asserted to the processor. The interrupt source is
  279. //! automatically disabled (via IntDisable()) if necessary.
  280. //!
  281. //! \sa IntRegister() for important information about registering interrupt
  282. //! handlers.
  283. //!
  284. //! \return None.
  285. //
  286. //*****************************************************************************
  287. void
  288. IntUnregister(unsigned long ulInterrupt)
  289. {
  290. //
  291. // Check the arguments.
  292. //
  293. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  294. //
  295. // Reset the interrupt handler.
  296. //
  297. g_pfnRAMVectors[ulInterrupt] = IntDefaultHandler;
  298. }
  299. //*****************************************************************************
  300. //
  301. //! Sets the priority grouping of the interrupt controller.
  302. //!
  303. //! \param ulBits specifies the number of bits of preemptable priority.
  304. //!
  305. //! This function specifies the split between preemptable priority levels and
  306. //! subpriority levels in the interrupt priority specification. The range of
  307. //! the grouping values are dependent upon the hardware implementation; on
  308. //! the Stellaris family, three bits are available for hardware interrupt
  309. //! prioritization and therefore priority grouping values of three through
  310. //! seven have the same effect.
  311. //!
  312. //! \return None.
  313. //
  314. //*****************************************************************************
  315. void
  316. IntPriorityGroupingSet(unsigned long ulBits)
  317. {
  318. //
  319. // Check the arguments.
  320. //
  321. ASSERT(ulBits < NUM_PRIORITY);
  322. //
  323. // Set the priority grouping.
  324. //
  325. HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | g_pulPriority[ulBits];
  326. }
  327. //*****************************************************************************
  328. //
  329. //! Gets the priority grouping of the interrupt controller.
  330. //!
  331. //! This function returns the split between preemptable priority levels and
  332. //! subpriority levels in the interrupt priority specification.
  333. //!
  334. //! \return The number of bits of preemptable priority.
  335. //
  336. //*****************************************************************************
  337. unsigned long
  338. IntPriorityGroupingGet(void)
  339. {
  340. unsigned long ulLoop, ulValue;
  341. //
  342. // Read the priority grouping.
  343. //
  344. ulValue = HWREG(NVIC_APINT) & NVIC_APINT_PRIGROUP_M;
  345. //
  346. // Loop through the priority grouping values.
  347. //
  348. for(ulLoop = 0; ulLoop < NUM_PRIORITY; ulLoop++)
  349. {
  350. //
  351. // Stop looping if this value matches.
  352. //
  353. if(ulValue == g_pulPriority[ulLoop])
  354. {
  355. break;
  356. }
  357. }
  358. //
  359. // Return the number of priority bits.
  360. //
  361. return(ulLoop);
  362. }
  363. //*****************************************************************************
  364. //
  365. //! Sets the priority of an interrupt.
  366. //!
  367. //! \param ulInterrupt specifies the interrupt in question.
  368. //! \param ucPriority specifies the priority of the interrupt.
  369. //!
  370. //! This function is used to set the priority of an interrupt. When multiple
  371. //! interrupts are asserted simultaneously, the ones with the highest priority
  372. //! are processed before the lower priority interrupts. Smaller numbers
  373. //! correspond to higher interrupt priorities; priority 0 is the highest
  374. //! interrupt priority.
  375. //!
  376. //! The hardware priority mechanism only looks at the upper N bits of the
  377. //! priority level (where N is 3 for the Stellaris family), so any
  378. //! prioritization must be performed in those bits. The remaining bits can be
  379. //! used to sub-prioritize the interrupt sources, and may be used by the
  380. //! hardware priority mechanism on a future part. This arrangement allows
  381. //! priorities to migrate to different NVIC implementations without changing
  382. //! the gross prioritization of the interrupts.
  383. //!
  384. //! \return None.
  385. //
  386. //*****************************************************************************
  387. void
  388. IntPrioritySet(unsigned long ulInterrupt, unsigned char ucPriority)
  389. {
  390. unsigned long ulTemp;
  391. //
  392. // Check the arguments.
  393. //
  394. ASSERT((ulInterrupt >= 4) && (ulInterrupt < NUM_INTERRUPTS));
  395. //
  396. // Set the interrupt priority.
  397. //
  398. ulTemp = HWREG(g_pulRegs[ulInterrupt >> 2]);
  399. ulTemp &= ~(0xFF << (8 * (ulInterrupt & 3)));
  400. ulTemp |= ucPriority << (8 * (ulInterrupt & 3));
  401. HWREG(g_pulRegs[ulInterrupt >> 2]) = ulTemp;
  402. }
  403. //*****************************************************************************
  404. //
  405. //! Gets the priority of an interrupt.
  406. //!
  407. //! \param ulInterrupt specifies the interrupt in question.
  408. //!
  409. //! This function gets the priority of an interrupt. See IntPrioritySet() for
  410. //! a definition of the priority value.
  411. //!
  412. //! \return Returns the interrupt priority, or -1 if an invalid interrupt was
  413. //! specified.
  414. //
  415. //*****************************************************************************
  416. long
  417. IntPriorityGet(unsigned long ulInterrupt)
  418. {
  419. //
  420. // Check the arguments.
  421. //
  422. ASSERT((ulInterrupt >= 4) && (ulInterrupt < NUM_INTERRUPTS));
  423. //
  424. // Return the interrupt priority.
  425. //
  426. return((HWREG(g_pulRegs[ulInterrupt >> 2]) >> (8 * (ulInterrupt & 3))) &
  427. 0xFF);
  428. }
  429. //*****************************************************************************
  430. //
  431. //! Enables an interrupt.
  432. //!
  433. //! \param ulInterrupt specifies the interrupt to be enabled.
  434. //!
  435. //! The specified interrupt is enabled in the interrupt controller. Other
  436. //! enables for the interrupt (such as at the peripheral level) are unaffected
  437. //! by this function.
  438. //!
  439. //! \return None.
  440. //
  441. //*****************************************************************************
  442. void
  443. IntEnable(unsigned long ulInterrupt)
  444. {
  445. //
  446. // Check the arguments.
  447. //
  448. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  449. //
  450. // Determine the interrupt to enable.
  451. //
  452. if(ulInterrupt == FAULT_MPU)
  453. {
  454. //
  455. // Enable the MemManage interrupt.
  456. //
  457. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_MEM;
  458. }
  459. else if(ulInterrupt == FAULT_BUS)
  460. {
  461. //
  462. // Enable the bus fault interrupt.
  463. //
  464. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_BUS;
  465. }
  466. else if(ulInterrupt == FAULT_USAGE)
  467. {
  468. //
  469. // Enable the usage fault interrupt.
  470. //
  471. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_USAGE;
  472. }
  473. else if(ulInterrupt == FAULT_SYSTICK)
  474. {
  475. //
  476. // Enable the System Tick interrupt.
  477. //
  478. HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN;
  479. }
  480. else if(ulInterrupt >= 16)
  481. {
  482. //
  483. // Enable the general interrupt.
  484. //
  485. HWREG(g_pulEnRegs[(ulInterrupt - 16) / 32]) =
  486. 1 << ((ulInterrupt - 16) & 31);
  487. }
  488. }
  489. //*****************************************************************************
  490. //
  491. //! Disables an interrupt.
  492. //!
  493. //! \param ulInterrupt specifies the interrupt to be disabled.
  494. //!
  495. //! The specified interrupt is disabled in the interrupt controller. Other
  496. //! enables for the interrupt (such as at the peripheral level) are unaffected
  497. //! by this function.
  498. //!
  499. //! \return None.
  500. //
  501. //*****************************************************************************
  502. void
  503. IntDisable(unsigned long ulInterrupt)
  504. {
  505. //
  506. // Check the arguments.
  507. //
  508. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  509. //
  510. // Determine the interrupt to disable.
  511. //
  512. if(ulInterrupt == FAULT_MPU)
  513. {
  514. //
  515. // Disable the MemManage interrupt.
  516. //
  517. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_MEM);
  518. }
  519. else if(ulInterrupt == FAULT_BUS)
  520. {
  521. //
  522. // Disable the bus fault interrupt.
  523. //
  524. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_BUS);
  525. }
  526. else if(ulInterrupt == FAULT_USAGE)
  527. {
  528. //
  529. // Disable the usage fault interrupt.
  530. //
  531. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_USAGE);
  532. }
  533. else if(ulInterrupt == FAULT_SYSTICK)
  534. {
  535. //
  536. // Disable the System Tick interrupt.
  537. //
  538. HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN);
  539. }
  540. else if(ulInterrupt >= 16)
  541. {
  542. //
  543. // Disable the general interrupt.
  544. //
  545. HWREG(g_pulDisRegs[(ulInterrupt - 16) / 32]) =
  546. 1 << ((ulInterrupt - 16) & 31);
  547. }
  548. }
  549. //*****************************************************************************
  550. //
  551. //! Pends an interrupt.
  552. //!
  553. //! \param ulInterrupt specifies the interrupt to be pended.
  554. //!
  555. //! The specified interrupt is pended in the interrupt controller. Pending an
  556. //! interrupt causes the interrupt controller to execute the corresponding
  557. //! interrupt handler at the next available time, based on the current
  558. //! interrupt state priorities. For example, if called by a higher priority
  559. //! interrupt handler, the specified interrupt handler is not called until
  560. //! after the current interrupt handler has completed execution. The interrupt
  561. //! must have been enabled for it to be called.
  562. //!
  563. //! \return None.
  564. //
  565. //*****************************************************************************
  566. void
  567. IntPendSet(unsigned long ulInterrupt)
  568. {
  569. //
  570. // Check the arguments.
  571. //
  572. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  573. //
  574. // Determine the interrupt to pend.
  575. //
  576. if(ulInterrupt == FAULT_NMI)
  577. {
  578. //
  579. // Pend the NMI interrupt.
  580. //
  581. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_NMI_SET;
  582. }
  583. else if(ulInterrupt == FAULT_PENDSV)
  584. {
  585. //
  586. // Pend the PendSV interrupt.
  587. //
  588. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PEND_SV;
  589. }
  590. else if(ulInterrupt == FAULT_SYSTICK)
  591. {
  592. //
  593. // Pend the SysTick interrupt.
  594. //
  595. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTSET;
  596. }
  597. else if(ulInterrupt >= 16)
  598. {
  599. //
  600. // Pend the general interrupt.
  601. //
  602. HWREG(g_pulPendRegs[(ulInterrupt - 16) / 32]) =
  603. 1 << ((ulInterrupt - 16) & 31);
  604. }
  605. }
  606. //*****************************************************************************
  607. //
  608. //! Unpends an interrupt.
  609. //!
  610. //! \param ulInterrupt specifies the interrupt to be unpended.
  611. //!
  612. //! The specified interrupt is unpended in the interrupt controller. Unpending
  613. //! an interrupt causes any previously generated interrupts that have not been
  614. //! handled yet (due to higher priority interrupts or the interrupt not having
  615. //! been enabled yet) to be discarded.
  616. //!
  617. //! \return None.
  618. //
  619. //*****************************************************************************
  620. void
  621. IntPendClear(unsigned long ulInterrupt)
  622. {
  623. //
  624. // Check the arguments.
  625. //
  626. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  627. //
  628. // Determine the interrupt to unpend.
  629. //
  630. if(ulInterrupt == FAULT_PENDSV)
  631. {
  632. //
  633. // Unpend the PendSV interrupt.
  634. //
  635. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_UNPEND_SV;
  636. }
  637. else if(ulInterrupt == FAULT_SYSTICK)
  638. {
  639. //
  640. // Unpend the SysTick interrupt.
  641. //
  642. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTCLR;
  643. }
  644. else if(ulInterrupt >= 16)
  645. {
  646. //
  647. // Unpend the general interrupt.
  648. //
  649. HWREG(g_pulUnpendRegs[(ulInterrupt - 16) / 32]) =
  650. 1 << ((ulInterrupt - 16) & 31);
  651. }
  652. }
  653. //*****************************************************************************
  654. //
  655. //! Sets the priority masking level
  656. //!
  657. //! \param ulPriorityMask is the priority level that is masked.
  658. //!
  659. //! This function sets the interrupt priority masking level so that all
  660. //! interrupts at the specified or lesser priority level are masked. Masking
  661. //! interrupts can be used to globally disable a set of interrupts with
  662. //! priority below a predetermined threshold. A value of 0 disables priority
  663. //! masking.
  664. //!
  665. //! Smaller numbers correspond to higher interrupt priorities. So for example
  666. //! a priority level mask of 4 allows interrupts of priority level 0-3,
  667. //! and interrupts with a numerical priority of 4 and greater are blocked.
  668. //!
  669. //! The hardware priority mechanism only looks at the upper N bits of the
  670. //! priority level (where N is 3 for the Stellaris family), so any
  671. //! prioritization must be performed in those bits.
  672. //!
  673. //! \return None.
  674. //
  675. //*****************************************************************************
  676. void
  677. IntPriorityMaskSet(unsigned long ulPriorityMask)
  678. {
  679. CPUbasepriSet(ulPriorityMask);
  680. }
  681. //*****************************************************************************
  682. //
  683. //! Gets the priority masking level
  684. //!
  685. //! This function gets the current setting of the interrupt priority masking
  686. //! level. The value returned is the priority level such that all interrupts
  687. //! of that and lesser priority are masked. A value of 0 means that priority
  688. //! masking is disabled.
  689. //!
  690. //! Smaller numbers correspond to higher interrupt priorities. So for example
  691. //! a priority level mask of 4 allows interrupts of priority level 0-3,
  692. //! and interrupts with a numerical priority of 4 and greater are blocked.
  693. //!
  694. //! The hardware priority mechanism only looks at the upper N bits of the
  695. //! priority level (where N is 3 for the Stellaris family), so any
  696. //! prioritization must be performed in those bits.
  697. //!
  698. //! \return Returns the value of the interrupt priority level mask.
  699. //
  700. //*****************************************************************************
  701. unsigned long
  702. IntPriorityMaskGet(void)
  703. {
  704. return(CPUbasepriGet());
  705. }
  706. //*****************************************************************************
  707. //
  708. // Close the Doxygen group.
  709. //! @}
  710. //
  711. //*****************************************************************************