interrupt.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  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 8049 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. //! Allows the processor to respond to interrupts. This does not affect the
  159. //! set of interrupts enabled in the interrupt controller; it just gates the
  160. //! 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 will occur 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. //! Prevents the processor from receiving interrupts. This does not affect the
  185. //! set of interrupts enabled in the interrupt controller; it just gates the
  186. //! single interrupt from the controller to the processor.
  187. //!
  188. //! \note Previously, this function had no return value. As such, it was
  189. //! possible to include <tt>interrupt.h</tt> and call this function without
  190. //! having included <tt>hw_types.h</tt>. Now that the return is a
  191. //! <tt>tBoolean</tt>, a compiler error will occur in this case. The solution
  192. //! is to include <tt>hw_types.h</tt> before including <tt>interrupt.h</tt>.
  193. //!
  194. //! \return Returns \b true if interrupts were already disabled when the
  195. //! function was called or \b false if they were initially enabled.
  196. //
  197. //*****************************************************************************
  198. tBoolean
  199. IntMasterDisable(void)
  200. {
  201. //
  202. // Disable processor interrupts.
  203. //
  204. return(CPUcpsid());
  205. }
  206. //*****************************************************************************
  207. //
  208. //! Registers a function to be called when an interrupt occurs.
  209. //!
  210. //! \param ulInterrupt specifies the interrupt in question.
  211. //! \param pfnHandler is a pointer to the function to be called.
  212. //!
  213. //! This function is used to specify the handler function to be called when the
  214. //! given interrupt is asserted to the processor. When the interrupt occurs,
  215. //! if it is enabled (via IntEnable()), the handler function is called in
  216. //! interrupt context. Since the handler function can preempt other code, care
  217. //! must be taken to protect memory or peripherals that are accessed by the
  218. //! handler and other non-handler code.
  219. //!
  220. //! \note The use of this function (directly or indirectly via a peripheral
  221. //! driver interrupt register function) moves the interrupt vector table from
  222. //! flash to SRAM. Therefore, care must be taken when linking the application
  223. //! to ensure that the SRAM vector table is located at the beginning of SRAM;
  224. //! otherwise NVIC will not look in the correct portion of memory for the
  225. //! vector table (it requires the vector table be on a 1 kB memory alignment).
  226. //! Normally, the SRAM vector table is so placed via the use of linker scripts.
  227. //! See the discussion of compile-time versus run-time interrupt handler
  228. //! registration in the introduction to this chapter.
  229. //!
  230. //! \return None.
  231. //
  232. //*****************************************************************************
  233. void
  234. IntRegister(unsigned long ulInterrupt, void (*pfnHandler)(void))
  235. {
  236. unsigned long ulIdx, ulValue;
  237. //
  238. // Check the arguments.
  239. //
  240. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  241. //
  242. // Make sure that the RAM vector table is correctly aligned.
  243. //
  244. ASSERT(((unsigned long)g_pfnRAMVectors & 0x000003ff) == 0);
  245. //
  246. // See if the RAM vector table has been initialized.
  247. //
  248. if(HWREG(NVIC_VTABLE) != (unsigned long)g_pfnRAMVectors)
  249. {
  250. //
  251. // Copy the vector table from the beginning of FLASH to the RAM vector
  252. // table.
  253. //
  254. ulValue = HWREG(NVIC_VTABLE);
  255. for(ulIdx = 0; ulIdx < NUM_INTERRUPTS; ulIdx++)
  256. {
  257. g_pfnRAMVectors[ulIdx] = (void (*)(void))HWREG((ulIdx * 4) +
  258. ulValue);
  259. }
  260. //
  261. // Point NVIC at the RAM vector table.
  262. //
  263. HWREG(NVIC_VTABLE) = (unsigned long)g_pfnRAMVectors;
  264. }
  265. //
  266. // Save the interrupt handler.
  267. //
  268. g_pfnRAMVectors[ulInterrupt] = pfnHandler;
  269. }
  270. //*****************************************************************************
  271. //
  272. //! Unregisters the function to be called when an interrupt occurs.
  273. //!
  274. //! \param ulInterrupt specifies the interrupt in question.
  275. //!
  276. //! This function is used to indicate that no handler should be called when the
  277. //! given interrupt is asserted to the processor. The interrupt source is
  278. //! automatically disabled (via IntDisable()) if necessary.
  279. //!
  280. //! \sa IntRegister() for important information about registering interrupt
  281. //! handlers.
  282. //!
  283. //! \return None.
  284. //
  285. //*****************************************************************************
  286. void
  287. IntUnregister(unsigned long ulInterrupt)
  288. {
  289. //
  290. // Check the arguments.
  291. //
  292. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  293. //
  294. // Reset the interrupt handler.
  295. //
  296. g_pfnRAMVectors[ulInterrupt] = IntDefaultHandler;
  297. }
  298. //*****************************************************************************
  299. //
  300. //! Sets the priority grouping of the interrupt controller.
  301. //!
  302. //! \param ulBits specifies the number of bits of preemptable priority.
  303. //!
  304. //! This function specifies the split between preemptable priority levels and
  305. //! subpriority levels in the interrupt priority specification. The range of
  306. //! the grouping values are dependent upon the hardware implementation; on
  307. //! the Stellaris family, three bits are available for hardware interrupt
  308. //! prioritization and therefore priority grouping values of three through
  309. //! seven have the same effect.
  310. //!
  311. //! \return None.
  312. //
  313. //*****************************************************************************
  314. void
  315. IntPriorityGroupingSet(unsigned long ulBits)
  316. {
  317. //
  318. // Check the arguments.
  319. //
  320. ASSERT(ulBits < NUM_PRIORITY);
  321. //
  322. // Set the priority grouping.
  323. //
  324. HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | g_pulPriority[ulBits];
  325. }
  326. //*****************************************************************************
  327. //
  328. //! Gets the priority grouping of the interrupt controller.
  329. //!
  330. //! This function returns the split between preemptable priority levels and
  331. //! subpriority levels in the interrupt priority specification.
  332. //!
  333. //! \return The number of bits of preemptable priority.
  334. //
  335. //*****************************************************************************
  336. unsigned long
  337. IntPriorityGroupingGet(void)
  338. {
  339. unsigned long ulLoop, ulValue;
  340. //
  341. // Read the priority grouping.
  342. //
  343. ulValue = HWREG(NVIC_APINT) & NVIC_APINT_PRIGROUP_M;
  344. //
  345. // Loop through the priority grouping values.
  346. //
  347. for(ulLoop = 0; ulLoop < NUM_PRIORITY; ulLoop++)
  348. {
  349. //
  350. // Stop looping if this value matches.
  351. //
  352. if(ulValue == g_pulPriority[ulLoop])
  353. {
  354. break;
  355. }
  356. }
  357. //
  358. // Return the number of priority bits.
  359. //
  360. return(ulLoop);
  361. }
  362. //*****************************************************************************
  363. //
  364. //! Sets the priority of an interrupt.
  365. //!
  366. //! \param ulInterrupt specifies the interrupt in question.
  367. //! \param ucPriority specifies the priority of the interrupt.
  368. //!
  369. //! This function is used to set the priority of an interrupt. When multiple
  370. //! interrupts are asserted simultaneously, the ones with the highest priority
  371. //! are processed before the lower priority interrupts. Smaller numbers
  372. //! correspond to higher interrupt priorities; priority 0 is the highest
  373. //! interrupt priority.
  374. //!
  375. //! The hardware priority mechanism will only look at the upper N bits of the
  376. //! priority level (where N is 3 for the Stellaris family), so any
  377. //! prioritization must be performed in those bits. The remaining bits can be
  378. //! used to sub-prioritize the interrupt sources, and may be used by the
  379. //! hardware priority mechanism on a future part. This arrangement allows
  380. //! priorities to migrate to different NVIC implementations without changing
  381. //! the gross prioritization of the interrupts.
  382. //!
  383. //! \return None.
  384. //
  385. //*****************************************************************************
  386. void
  387. IntPrioritySet(unsigned long ulInterrupt, unsigned char ucPriority)
  388. {
  389. unsigned long ulTemp;
  390. //
  391. // Check the arguments.
  392. //
  393. ASSERT((ulInterrupt >= 4) && (ulInterrupt < NUM_INTERRUPTS));
  394. //
  395. // Set the interrupt priority.
  396. //
  397. ulTemp = HWREG(g_pulRegs[ulInterrupt >> 2]);
  398. ulTemp &= ~(0xFF << (8 * (ulInterrupt & 3)));
  399. ulTemp |= ucPriority << (8 * (ulInterrupt & 3));
  400. HWREG(g_pulRegs[ulInterrupt >> 2]) = ulTemp;
  401. }
  402. //*****************************************************************************
  403. //
  404. //! Gets the priority of an interrupt.
  405. //!
  406. //! \param ulInterrupt specifies the interrupt in question.
  407. //!
  408. //! This function gets the priority of an interrupt. See IntPrioritySet() for
  409. //! a definition of the priority value.
  410. //!
  411. //! \return Returns the interrupt priority, or -1 if an invalid interrupt was
  412. //! specified.
  413. //
  414. //*****************************************************************************
  415. long
  416. IntPriorityGet(unsigned long ulInterrupt)
  417. {
  418. //
  419. // Check the arguments.
  420. //
  421. ASSERT((ulInterrupt >= 4) && (ulInterrupt < NUM_INTERRUPTS));
  422. //
  423. // Return the interrupt priority.
  424. //
  425. return((HWREG(g_pulRegs[ulInterrupt >> 2]) >> (8 * (ulInterrupt & 3))) &
  426. 0xFF);
  427. }
  428. //*****************************************************************************
  429. //
  430. //! Enables an interrupt.
  431. //!
  432. //! \param ulInterrupt specifies the interrupt to be enabled.
  433. //!
  434. //! The specified interrupt is enabled in the interrupt controller. Other
  435. //! enables for the interrupt (such as at the peripheral level) are unaffected
  436. //! by this function.
  437. //!
  438. //! \return None.
  439. //
  440. //*****************************************************************************
  441. void
  442. IntEnable(unsigned long ulInterrupt)
  443. {
  444. //
  445. // Check the arguments.
  446. //
  447. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  448. //
  449. // Determine the interrupt to enable.
  450. //
  451. if(ulInterrupt == FAULT_MPU)
  452. {
  453. //
  454. // Enable the MemManage interrupt.
  455. //
  456. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_MEM;
  457. }
  458. else if(ulInterrupt == FAULT_BUS)
  459. {
  460. //
  461. // Enable the bus fault interrupt.
  462. //
  463. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_BUS;
  464. }
  465. else if(ulInterrupt == FAULT_USAGE)
  466. {
  467. //
  468. // Enable the usage fault interrupt.
  469. //
  470. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_USAGE;
  471. }
  472. else if(ulInterrupt == FAULT_SYSTICK)
  473. {
  474. //
  475. // Enable the System Tick interrupt.
  476. //
  477. HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN;
  478. }
  479. else if(ulInterrupt >= 16)
  480. {
  481. //
  482. // Enable the general interrupt.
  483. //
  484. HWREG(g_pulEnRegs[(ulInterrupt - 16) / 32]) =
  485. 1 << ((ulInterrupt - 16) & 31);
  486. }
  487. }
  488. //*****************************************************************************
  489. //
  490. //! Disables an interrupt.
  491. //!
  492. //! \param ulInterrupt specifies the interrupt to be disabled.
  493. //!
  494. //! The specified interrupt is disabled in the interrupt controller. Other
  495. //! enables for the interrupt (such as at the peripheral level) are unaffected
  496. //! by this function.
  497. //!
  498. //! \return None.
  499. //
  500. //*****************************************************************************
  501. void
  502. IntDisable(unsigned long ulInterrupt)
  503. {
  504. //
  505. // Check the arguments.
  506. //
  507. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  508. //
  509. // Determine the interrupt to disable.
  510. //
  511. if(ulInterrupt == FAULT_MPU)
  512. {
  513. //
  514. // Disable the MemManage interrupt.
  515. //
  516. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_MEM);
  517. }
  518. else if(ulInterrupt == FAULT_BUS)
  519. {
  520. //
  521. // Disable the bus fault interrupt.
  522. //
  523. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_BUS);
  524. }
  525. else if(ulInterrupt == FAULT_USAGE)
  526. {
  527. //
  528. // Disable the usage fault interrupt.
  529. //
  530. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_USAGE);
  531. }
  532. else if(ulInterrupt == FAULT_SYSTICK)
  533. {
  534. //
  535. // Disable the System Tick interrupt.
  536. //
  537. HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN);
  538. }
  539. else if(ulInterrupt >= 16)
  540. {
  541. //
  542. // Disable the general interrupt.
  543. //
  544. HWREG(g_pulDisRegs[(ulInterrupt - 16) / 32]) =
  545. 1 << ((ulInterrupt - 16) & 31);
  546. }
  547. }
  548. //*****************************************************************************
  549. //
  550. //! Pends an interrupt.
  551. //!
  552. //! \param ulInterrupt specifies the interrupt to be pended.
  553. //!
  554. //! The specified interrupt is pended in the interrupt controller. This will
  555. //! cause the interrupt controller to execute the corresponding interrupt
  556. //! handler at the next available time, based on the current interrupt state
  557. //! priorities. For example, if called by a higher priority interrupt handler,
  558. //! the specified interrupt handler will not be called until after the current
  559. //! interrupt handler has completed execution. The interrupt must have been
  560. //! enabled for it to be called.
  561. //!
  562. //! \return None.
  563. //
  564. //*****************************************************************************
  565. void
  566. IntPendSet(unsigned long ulInterrupt)
  567. {
  568. //
  569. // Check the arguments.
  570. //
  571. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  572. //
  573. // Determine the interrupt to pend.
  574. //
  575. if(ulInterrupt == FAULT_NMI)
  576. {
  577. //
  578. // Pend the NMI interrupt.
  579. //
  580. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_NMI_SET;
  581. }
  582. else if(ulInterrupt == FAULT_PENDSV)
  583. {
  584. //
  585. // Pend the PendSV interrupt.
  586. //
  587. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PEND_SV;
  588. }
  589. else if(ulInterrupt == FAULT_SYSTICK)
  590. {
  591. //
  592. // Pend the SysTick interrupt.
  593. //
  594. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTSET;
  595. }
  596. else if(ulInterrupt >= 16)
  597. {
  598. //
  599. // Pend the general interrupt.
  600. //
  601. HWREG(g_pulPendRegs[(ulInterrupt - 16) / 32]) =
  602. 1 << ((ulInterrupt - 16) & 31);
  603. }
  604. }
  605. //*****************************************************************************
  606. //
  607. //! Unpends an interrupt.
  608. //!
  609. //! \param ulInterrupt specifies the interrupt to be unpended.
  610. //!
  611. //! The specified interrupt is unpended in the interrupt controller. This will
  612. //! cause any previously generated interrupts that have not been handled yet
  613. //! (due to higher priority interrupts or the interrupt no having been enabled
  614. //! yet) to be discarded.
  615. //!
  616. //! \return None.
  617. //
  618. //*****************************************************************************
  619. void
  620. IntPendClear(unsigned long ulInterrupt)
  621. {
  622. //
  623. // Check the arguments.
  624. //
  625. ASSERT(ulInterrupt < NUM_INTERRUPTS);
  626. //
  627. // Determine the interrupt to unpend.
  628. //
  629. if(ulInterrupt == FAULT_PENDSV)
  630. {
  631. //
  632. // Unpend the PendSV interrupt.
  633. //
  634. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_UNPEND_SV;
  635. }
  636. else if(ulInterrupt == FAULT_SYSTICK)
  637. {
  638. //
  639. // Unpend the SysTick interrupt.
  640. //
  641. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTCLR;
  642. }
  643. else if(ulInterrupt >= 16)
  644. {
  645. //
  646. // Unpend the general interrupt.
  647. //
  648. HWREG(g_pulUnpendRegs[(ulInterrupt - 16) / 32]) =
  649. 1 << ((ulInterrupt - 16) & 31);
  650. }
  651. }
  652. //*****************************************************************************
  653. //
  654. //! Sets the priority masking level
  655. //!
  656. //! \param ulPriorityMask is the priority level that is masked.
  657. //!
  658. //! This function sets the interrupt priority masking level so that all
  659. //! interrupts at the specified or lesser priority level is masked. This
  660. //! can be used to globally disable a set of interrupts with priority below
  661. //! a predetermined threshold. A value of 0 disables priority
  662. //! masking.
  663. //!
  664. //! Smaller numbers correspond to higher interrupt priorities. So for example
  665. //! a priority level mask of 4 will allow interrupts of priority level 0-3,
  666. //! and interrupts with a numerical priority of 4 and greater is blocked.
  667. //!
  668. //! The hardware priority mechanism will only look at the upper N bits of the
  669. //! priority level (where N is 3 for the Stellaris family), so any
  670. //! prioritization must be performed in those bits.
  671. //!
  672. //! \return None.
  673. //
  674. //*****************************************************************************
  675. void
  676. IntPriorityMaskSet(unsigned long ulPriorityMask)
  677. {
  678. CPUbasepriSet(ulPriorityMask);
  679. }
  680. //*****************************************************************************
  681. //
  682. //! Gets the priority masking level
  683. //!
  684. //! This function gets the current setting of the interrupt priority masking
  685. //! level. The value returned is the priority level such that all interrupts
  686. //! of that and lesser priority are masked. A value of 0 means that priority
  687. //! masking is disabled.
  688. //!
  689. //! Smaller numbers correspond to higher interrupt priorities. So for example
  690. //! a priority level mask of 4 will allow interrupts of priority level 0-3,
  691. //! and interrupts with a numerical priority of 4 and greater is blocked.
  692. //!
  693. //! The hardware priority mechanism will only look at the upper N bits of the
  694. //! priority level (where N is 3 for the Stellaris family), so any
  695. //! prioritization must be performed in those bits.
  696. //!
  697. //! \return Returns the value of the interrupt priority level mask.
  698. //
  699. //*****************************************************************************
  700. unsigned long
  701. IntPriorityMaskGet(void)
  702. {
  703. return(CPUbasepriGet());
  704. }
  705. //*****************************************************************************
  706. //
  707. // Close the Doxygen group.
  708. //! @}
  709. //
  710. //*****************************************************************************