interrupt.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. /******************************************************************************
  2. * Filename: interrupt.c
  3. * Revised: $Date: 2013-03-20 14:47:53 +0100 (Wed, 20 Mar 2013) $
  4. * Revision: $Revision: 9489 $
  5. *
  6. * Description: Driver for the NVIC Interrupt Controller.
  7. *
  8. * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
  9. *
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. *
  15. * Redistributions of source code must retain the above copyright
  16. * notice, this list of conditions and the following disclaimer.
  17. *
  18. * Redistributions in binary form must reproduce the above copyright
  19. * notice, this list of conditions and the following disclaimer in the
  20. * documentation and/or other materials provided with the distribution.
  21. *
  22. * Neither the name of Texas Instruments Incorporated nor the names of
  23. * its contributors may be used to endorse or promote products derived
  24. * from this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  29. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  30. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  31. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  32. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  33. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  34. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  36. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. ******************************************************************************/
  39. //*****************************************************************************
  40. //
  41. //! \addtogroup interrupt_api
  42. //! @{
  43. //
  44. //*****************************************************************************
  45. #include "hw_ints.h"
  46. #include "hw_nvic.h"
  47. #include "hw_sys_ctrl.h"
  48. #include "cpu.h"
  49. #include "debug.h"
  50. #include "interrupt.h"
  51. //*****************************************************************************
  52. //
  53. // This is a mapping between priority grouping encodings and the number of
  54. // preemption priority bits.
  55. //
  56. //*****************************************************************************
  57. static const uint32_t g_pui32Priority[] =
  58. {
  59. NVIC_APINT_PRIGROUP_0_8, NVIC_APINT_PRIGROUP_1_7, NVIC_APINT_PRIGROUP_2_6,
  60. NVIC_APINT_PRIGROUP_3_5, NVIC_APINT_PRIGROUP_4_4, NVIC_APINT_PRIGROUP_5_3,
  61. NVIC_APINT_PRIGROUP_6_2, NVIC_APINT_PRIGROUP_7_1
  62. };
  63. //*****************************************************************************
  64. //
  65. // This is a mapping between interrupt number and the register that contains
  66. // the priority encoding for that interrupt.
  67. //
  68. //*****************************************************************************
  69. static const uint32_t g_pui32Regs[] =
  70. {
  71. 0, NVIC_SYS_PRI1, NVIC_SYS_PRI2, NVIC_SYS_PRI3, NVIC_PRI0, NVIC_PRI1,
  72. NVIC_PRI2, NVIC_PRI3, NVIC_PRI4, NVIC_PRI5, NVIC_PRI6, NVIC_PRI7,
  73. NVIC_PRI8, NVIC_PRI9, NVIC_PRI10, NVIC_PRI11, NVIC_PRI12, NVIC_PRI13,
  74. NVIC_PRI14, NVIC_PRI15, NVIC_PRI16, NVIC_PRI17, NVIC_PRI18, NVIC_PRI19,
  75. NVIC_PRI20, NVIC_PRI21, NVIC_PRI22, NVIC_PRI23, NVIC_PRI24, NVIC_PRI25,
  76. NVIC_PRI26, NVIC_PRI27, NVIC_PRI28, NVIC_PRI29, NVIC_PRI30, NVIC_PRI31,
  77. NVIC_PRI32, NVIC_PRI33, NVIC_PRI34, NVIC_PRI35, NVIC_PRI36
  78. };
  79. //*****************************************************************************
  80. //
  81. // This is a mapping between interrupt number (for the peripheral interrupts
  82. // only) and the register that contains the interrupt enable for that
  83. // interrupt.
  84. //
  85. //*****************************************************************************
  86. static const uint32_t g_pui32EnRegs[] =
  87. {
  88. NVIC_EN0, NVIC_EN1, NVIC_EN2, NVIC_EN3, NVIC_EN4
  89. };
  90. //*****************************************************************************
  91. //
  92. // This is a mapping between interrupt number (for the peripheral interrupts
  93. // only) and the register that contains the interrupt disable for that
  94. // interrupt.
  95. //
  96. //*****************************************************************************
  97. static const uint32_t g_pui32DisRegs[] =
  98. {
  99. NVIC_DIS0, NVIC_DIS1, NVIC_DIS2, NVIC_DIS3, NVIC_DIS4
  100. };
  101. //*****************************************************************************
  102. //
  103. // This is a mapping between interrupt number (for the peripheral interrupts
  104. // only) and the register that contains the interrupt pend for that interrupt.
  105. //
  106. //*****************************************************************************
  107. static const uint32_t g_pui32PendRegs[] =
  108. {
  109. NVIC_PEND0, NVIC_PEND1, NVIC_PEND2, NVIC_PEND3, NVIC_PEND4
  110. };
  111. //*****************************************************************************
  112. //
  113. // This is a mapping between interrupt number (for the peripheral interrupts
  114. // only) and the register that contains the interrupt unpend for that
  115. // interrupt.
  116. //
  117. //*****************************************************************************
  118. static const uint32_t g_pui32UnpendRegs[] =
  119. {
  120. NVIC_UNPEND0, NVIC_UNPEND1, NVIC_UNPEND2, NVIC_UNPEND3, NVIC_UNPEND4
  121. };
  122. //*****************************************************************************
  123. //
  124. //! \internal
  125. //! The default interrupt handler
  126. //!
  127. //! This is the default interrupt handler for all interrupts. It simply loops
  128. //! forever so that the system state is preserved for observation by a
  129. //! debugger. Since interrupts should be disabled before unregistering the
  130. //! corresponding handler, this should never be called.
  131. //!
  132. //! \return None
  133. //
  134. //*****************************************************************************
  135. static void
  136. IntDefaultHandler(void)
  137. {
  138. //
  139. // Go into an infinite loop.
  140. //
  141. while(1)
  142. {
  143. }
  144. }
  145. //*****************************************************************************
  146. //
  147. // The processor vector table
  148. //
  149. // This contains a list of the handlers for the various interrupt sources in
  150. // the system. The layout of this list is defined by the hardware; assertion
  151. // of an interrupt causes the processor to start executing directly at the
  152. // address given in the corresponding location in this list.
  153. //
  154. //*****************************************************************************
  155. #if defined(__ICCARM__)
  156. #pragma data_alignment=1024
  157. static __no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) @ "VTABLE";
  158. #elif defined(__TI_COMPILER_VERSION__) || defined(DOXYGEN)
  159. #pragma DATA_ALIGN(g_pfnRAMVectors, 1024)
  160. #pragma DATA_SECTION(g_pfnRAMVectors, ".vtable")
  161. void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void);
  162. #else
  163. static __attribute__((section("vtable")))
  164. void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) __attribute__((aligned(1024)));
  165. #endif
  166. //*****************************************************************************
  167. //
  168. //! Enables the processor interrupt
  169. //!
  170. //! This function allows the processor to respond to interrupts. This does not
  171. //! affect the set of interrupts enabled in the interrupt controller; it just
  172. //! gates the single interrupt from the controller to the processor.
  173. //!
  174. //! \return Returns \b true if interrupts were disabled when the function was
  175. //! called or \b false if they were initially enabled.
  176. //
  177. //*****************************************************************************
  178. bool
  179. IntMasterEnable(void)
  180. {
  181. //
  182. // Enable processor interrupts.
  183. //
  184. return(CPUcpsie());
  185. }
  186. //*****************************************************************************
  187. //
  188. //! Disables the processor interrupt
  189. //!
  190. //! This function prevents the processor from receiving interrupts. This does
  191. //! not affect the set of interrupts enabled in the interrupt controller; it
  192. //! just gates the single interrupt from the controller to the processor.
  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. bool
  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 ui32Interrupt specifies the interrupt in question.
  211. //! \param pfnHandler is a pointer to the function to be called.
  212. //!
  213. //! This function specifies 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 (through IntEnable()), the handler function is called in
  216. //! interrupt context. Because 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 nonhandler code.
  219. //!
  220. //! \note This function (directly or indirectly through 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 through the use of linker
  227. //! scripts. See the discussion of compile-time versus runtime interrupt handler
  228. //! registration in the introduction to this chapter.
  229. //!
  230. //! \return None
  231. //
  232. //*****************************************************************************
  233. void
  234. IntRegister(uint32_t ui32Interrupt, void (*pfnHandler)(void))
  235. {
  236. uint32_t ui32Idx, ui32Value;
  237. //
  238. // Check the arguments.
  239. //
  240. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  241. // Check below could be removed in final application
  242. #ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP
  243. ASSERT(IntAltMapIsEnabled());
  244. #else
  245. ASSERT(~IntAltMapIsEnabled());
  246. #endif
  247. //
  248. // Make sure that the RAM vector table is correctly aligned.
  249. //
  250. ASSERT(((uint32_t)g_pfnRAMVectors & 0x000003ff) == 0);
  251. //
  252. // See if the RAM vector table has been initialized.
  253. //
  254. if(HWREG(NVIC_VTABLE) != (uint32_t)g_pfnRAMVectors)
  255. {
  256. //
  257. // Copy the vector table from the beginning of FLASH to the RAM vector
  258. // table.
  259. //
  260. ui32Value = HWREG(NVIC_VTABLE);
  261. for(ui32Idx = 0; ui32Idx < NUM_INTERRUPTS; ui32Idx++)
  262. {
  263. g_pfnRAMVectors[ui32Idx] = (void (*)(void))HWREG((ui32Idx * 4) +
  264. ui32Value);
  265. }
  266. //
  267. // Point NVIC at the RAM vector table.
  268. //
  269. HWREG(NVIC_VTABLE) = (uint32_t)g_pfnRAMVectors;
  270. }
  271. //
  272. // Save the interrupt handler.
  273. //
  274. g_pfnRAMVectors[ui32Interrupt] = pfnHandler;
  275. }
  276. //*****************************************************************************
  277. //
  278. //! Unregisters the function to be called when an interrupt occurs
  279. //!
  280. //! \param ui32Interrupt specifies the interrupt in question.
  281. //!
  282. //! This function indicates that no handler should be called when the
  283. //! given interrupt is asserted to the processor. The interrupt source is
  284. //! automatically disabled (through IntDisable()) if necessary.
  285. //!
  286. //! \sa See IntRegister() for important information about registering interrupt
  287. //! handlers.
  288. //!
  289. //! \return None
  290. //
  291. //*****************************************************************************
  292. void
  293. IntUnregister(uint32_t ui32Interrupt)
  294. {
  295. //
  296. // Check the arguments.
  297. //
  298. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  299. //
  300. // Check that at least one interrupt was dynamically registered
  301. // (by calling IntRegister())
  302. //
  303. ASSERT(HWREG(NVIC_VTABLE) == (uint32_t)g_pfnRAMVectors);
  304. // Check below could be removed in final application
  305. #ifdef CC2538_USE_ALTERNATE_INTERRUPT_MAP
  306. ASSERT(IntAltMapIsEnabled());
  307. #else
  308. ASSERT(~IntAltMapIsEnabled());
  309. #endif
  310. //
  311. // Reset the interrupt handler.
  312. //
  313. g_pfnRAMVectors[ui32Interrupt] = IntDefaultHandler;
  314. }
  315. //*****************************************************************************
  316. //
  317. //! Sets the priority grouping of the interrupt controller
  318. //!
  319. //! \param ui32Bits specifies the number of bits of preemptable priority.
  320. //!
  321. //! This function specifies the split between preemptable priority levels and
  322. //! subpriority levels in the interrupt priority specification. The range of
  323. //! the grouping values depend on the hardware implementation; on
  324. //! the CC2538 device family, 3 bits are available for hardware interrupt
  325. //! prioritization and therefore priority grouping values of three through
  326. //! seven have the same effect.
  327. //!
  328. //! \return None
  329. //
  330. //*****************************************************************************
  331. void
  332. IntPriorityGroupingSet(uint32_t ui32Bits)
  333. {
  334. //
  335. // Check the arguments.
  336. //
  337. ASSERT(ui32Bits < NUM_PRIORITY);
  338. //
  339. // Set the priority grouping.
  340. //
  341. HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | g_pui32Priority[ui32Bits];
  342. }
  343. //*****************************************************************************
  344. //
  345. //! Gets the priority grouping of the interrupt controller
  346. //!
  347. //! This function returns the split between preemptable priority levels and
  348. //! subpriority levels in the interrupt priority specification.
  349. //!
  350. //! \return Returns the number of bits of preemptable priority
  351. //
  352. //*****************************************************************************
  353. uint32_t
  354. IntPriorityGroupingGet(void)
  355. {
  356. uint32_t ui32Loop, ui32Value;
  357. //
  358. // Read the priority grouping.
  359. //
  360. ui32Value = HWREG(NVIC_APINT) & NVIC_APINT_PRIGROUP_M;
  361. //
  362. // Loop through the priority grouping values.
  363. //
  364. for(ui32Loop = 0; ui32Loop < NUM_PRIORITY; ui32Loop++)
  365. {
  366. //
  367. // Stop looping if this value matches.
  368. //
  369. if(ui32Value == g_pui32Priority[ui32Loop])
  370. {
  371. break;
  372. }
  373. }
  374. //
  375. // Return the number of priority bits.
  376. //
  377. return(ui32Loop);
  378. }
  379. //*****************************************************************************
  380. //
  381. //! Sets the priority of an interrupt
  382. //!
  383. //! \param ui32Interrupt specifies the interrupt in question.
  384. //! \param ui8Priority specifies the priority of the interrupt.
  385. //!
  386. //! This function sets the priority of an interrupt. When multiple
  387. //! interrupts are asserted simultaneously, those with the highest priority
  388. //! are processed before the lower priority interrupts. Smaller numbers
  389. //! correspond to higher interrupt priorities; priority 0 is the highest
  390. //! interrupt priority.
  391. //!
  392. //! The hardware priority mechanism will looks only at the upper N bits of the
  393. //! priority level (where N is 3 for the CC2538 device family), so any
  394. //! prioritization must be performed in those bits. The remaining bits can be
  395. //! used to subprioritize the interrupt sources, and may be used by the
  396. //! hardware priority mechanism on a future part. This arrangement allows
  397. //! priorities to migrate to different NVIC implementations without changing
  398. //! the gross prioritization of the interrupts.
  399. //! Thus for CC2538 to set a priority of 3, the parameter \e ui8Priority must
  400. //! be set to (3<<5).
  401. //!
  402. //! \return None
  403. //
  404. //*****************************************************************************
  405. void
  406. IntPrioritySet(uint32_t ui32Interrupt, uint8_t ui8Priority)
  407. {
  408. uint32_t ui32Temp;
  409. //
  410. // Check the arguments.
  411. //
  412. ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS));
  413. //
  414. // Set the interrupt priority.
  415. //
  416. ui32Temp = HWREG(g_pui32Regs[ui32Interrupt >> 2]);
  417. ui32Temp &= ~(0xFF << (8 * (ui32Interrupt & 3)));
  418. ui32Temp |= ui8Priority << (8 * (ui32Interrupt & 3));
  419. HWREG(g_pui32Regs[ui32Interrupt >> 2]) = ui32Temp;
  420. }
  421. //*****************************************************************************
  422. //
  423. //! Gets the priority of an interrupt
  424. //!
  425. //! \param ui32Interrupt specifies the interrupt in question.
  426. //!
  427. //! This function gets the priority of an interrupt. See IntPrioritySet() for
  428. //! a definition of the priority value.
  429. //!
  430. //! \return Returns the interrupt priority, or -1 if an invalid interrupt was
  431. //! specified
  432. //
  433. //*****************************************************************************
  434. int32_t
  435. IntPriorityGet(uint32_t ui32Interrupt)
  436. {
  437. //
  438. // Check the arguments.
  439. //
  440. ASSERT((ui32Interrupt >= 4) && (ui32Interrupt < NUM_INTERRUPTS));
  441. //
  442. // Return the interrupt priority.
  443. //
  444. return((HWREG(g_pui32Regs[ui32Interrupt >> 2]) >> (8 * (ui32Interrupt & 3))) &
  445. 0xFF);
  446. }
  447. //*****************************************************************************
  448. //
  449. //! Enables an interrupt
  450. //!
  451. //! \param ui32Interrupt specifies the interrupt to be enabled.
  452. //!
  453. //! This function enables the specified interrupt in the interrupt controller.
  454. //! Other enables for the interrupt (such as at the peripheral level) are
  455. //! unaffected by this function.
  456. //!
  457. //! \return None
  458. //
  459. //*****************************************************************************
  460. void
  461. IntEnable(uint32_t ui32Interrupt)
  462. {
  463. //
  464. // Check the arguments.
  465. //
  466. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  467. //
  468. // Determine the interrupt to enable.
  469. //
  470. if(ui32Interrupt == FAULT_MPU)
  471. {
  472. //
  473. // Enable the MemManage interrupt.
  474. //
  475. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_MEM;
  476. }
  477. else if(ui32Interrupt == FAULT_BUS)
  478. {
  479. //
  480. // Enable the bus fault interrupt.
  481. //
  482. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_BUS;
  483. }
  484. else if(ui32Interrupt == FAULT_USAGE)
  485. {
  486. //
  487. // Enable the usage fault interrupt.
  488. //
  489. HWREG(NVIC_SYS_HND_CTRL) |= NVIC_SYS_HND_CTRL_USAGE;
  490. }
  491. else if(ui32Interrupt == FAULT_SYSTICK)
  492. {
  493. //
  494. // Enable the System Tick interrupt.
  495. //
  496. HWREG(NVIC_ST_CTRL) |= NVIC_ST_CTRL_INTEN;
  497. }
  498. else if(ui32Interrupt >= 16)
  499. {
  500. //
  501. // Enable the general interrupt.
  502. //
  503. HWREG(g_pui32EnRegs[(ui32Interrupt - 16) / 32]) =
  504. 1 << ((ui32Interrupt - 16) & 31);
  505. }
  506. }
  507. //*****************************************************************************
  508. //
  509. //! Disables an interrupt
  510. //!
  511. //! \param ui32Interrupt specifies the interrupt to be disabled.
  512. //!
  513. //! This function disables specified interrupt in the interrupt controller.
  514. //! Other enables for the interrupt (such as at the peripheral level) are
  515. //! unaffected by this function.
  516. //!
  517. //! \return None
  518. //
  519. //*****************************************************************************
  520. void
  521. IntDisable(uint32_t ui32Interrupt)
  522. {
  523. //
  524. // Check the arguments.
  525. //
  526. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  527. //
  528. // Determine the interrupt to disable.
  529. //
  530. if(ui32Interrupt == FAULT_MPU)
  531. {
  532. //
  533. // Disable the MemManage interrupt.
  534. //
  535. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_MEM);
  536. }
  537. else if(ui32Interrupt == FAULT_BUS)
  538. {
  539. //
  540. // Disable the bus fault interrupt.
  541. //
  542. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_BUS);
  543. }
  544. else if(ui32Interrupt == FAULT_USAGE)
  545. {
  546. //
  547. // Disable the usage fault interrupt.
  548. //
  549. HWREG(NVIC_SYS_HND_CTRL) &= ~(NVIC_SYS_HND_CTRL_USAGE);
  550. }
  551. else if(ui32Interrupt == FAULT_SYSTICK)
  552. {
  553. //
  554. // Disable the System Tick interrupt.
  555. //
  556. HWREG(NVIC_ST_CTRL) &= ~(NVIC_ST_CTRL_INTEN);
  557. }
  558. else if(ui32Interrupt >= 16)
  559. {
  560. //
  561. // Disable the general interrupt.
  562. //
  563. HWREG(g_pui32DisRegs[(ui32Interrupt - 16) / 32]) =
  564. 1 << ((ui32Interrupt - 16) & 31);
  565. }
  566. }
  567. //*****************************************************************************
  568. //
  569. //! Pends an interrupt
  570. //!
  571. //! \param ui32Interrupt specifies the interrupt to be pended.
  572. //!
  573. //! This function pends the specified interrupt in the interrupt controller.
  574. //! This causes the interrupt controller to execute the corresponding interrupt
  575. //! handler at the next available time, based on the current interrupt state
  576. //! priorities. For example, if called by a higher priority interrupt handler,
  577. //! the specified interrupt handler is not called until after the current
  578. //! interrupt handler executes. The interrupt must have been enabled for
  579. //! it to be called.
  580. //!
  581. //! \return None
  582. //
  583. //*****************************************************************************
  584. void
  585. IntPendSet(uint32_t ui32Interrupt)
  586. {
  587. //
  588. // Check the arguments.
  589. //
  590. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  591. //
  592. // Determine the interrupt to pend.
  593. //
  594. if(ui32Interrupt == FAULT_NMI)
  595. {
  596. //
  597. // Pend the NMI interrupt.
  598. //
  599. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_NMI_SET;
  600. }
  601. else if(ui32Interrupt == FAULT_PENDSV)
  602. {
  603. //
  604. // Pend the PendSV interrupt.
  605. //
  606. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PEND_SV;
  607. }
  608. else if(ui32Interrupt == FAULT_SYSTICK)
  609. {
  610. //
  611. // Pend the SysTick interrupt.
  612. //
  613. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTSET;
  614. }
  615. else if(ui32Interrupt >= 16)
  616. {
  617. //
  618. // Pend the general interrupt.
  619. //
  620. HWREG(g_pui32PendRegs[(ui32Interrupt - 16) / 32]) =
  621. 1 << ((ui32Interrupt - 16) & 31);
  622. }
  623. }
  624. //*****************************************************************************
  625. //
  626. //! Unpends an interrupt
  627. //!
  628. //! \param ui32Interrupt specifies the interrupt to be unpended.
  629. //!
  630. //! This function unpends the specified interrupt in the interrupt controller.
  631. //! This will cause any previously generated interrupts that have not been
  632. //! handled yet (due to higher priority interrupts or the interrupt no having
  633. //! been enabled yet) to be discarded.
  634. //!
  635. //! \return None
  636. //
  637. //*****************************************************************************
  638. void
  639. IntPendClear(uint32_t ui32Interrupt)
  640. {
  641. //
  642. // Check the arguments.
  643. //
  644. ASSERT(ui32Interrupt < NUM_INTERRUPTS);
  645. //
  646. // Determine the interrupt to unpend.
  647. //
  648. if(ui32Interrupt == FAULT_PENDSV)
  649. {
  650. //
  651. // Unpend the PendSV interrupt.
  652. //
  653. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_UNPEND_SV;
  654. }
  655. else if(ui32Interrupt == FAULT_SYSTICK)
  656. {
  657. //
  658. // Unpend the SysTick interrupt.
  659. //
  660. HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTCLR;
  661. }
  662. else if(ui32Interrupt >= 16)
  663. {
  664. //
  665. // Unpend the general interrupt.
  666. //
  667. HWREG(g_pui32UnpendRegs[(ui32Interrupt - 16) / 32]) =
  668. 1 << ((ui32Interrupt - 16) & 31);
  669. }
  670. }
  671. //*****************************************************************************
  672. //
  673. //! Sets the priority masking level
  674. //!
  675. //! \param ui32PriorityMask is the priority level that will be masked.
  676. //!
  677. //! This function sets the interrupt priority masking level so that all
  678. //! interrupts at the specified or lesser priority level is masked. This
  679. //! can be used to globally disable a set of interrupts with priority below
  680. //! a predetermined threshold. A value of 0 disables priority
  681. //! masking.
  682. //!
  683. //! Smaller numbers correspond to higher interrupt priorities. For example,
  684. //! a priority level mask of 4 allows interrupts of priority level 0-3,
  685. //! and interrupts with a numerical priority of 4 and greater are blocked.
  686. //!
  687. //! The hardware priority mechanism looks only at the upper N bits of the
  688. //! priority level (where N is 3 for the CC2538 device family), so any
  689. //! prioritization must be performed in those bits.
  690. //!
  691. //! \return None
  692. //
  693. //*****************************************************************************
  694. void
  695. IntPriorityMaskSet(uint32_t ui32PriorityMask)
  696. {
  697. CPUbasepriSet(ui32PriorityMask);
  698. }
  699. //*****************************************************************************
  700. //
  701. //! Gets the priority masking level
  702. //!
  703. //! This function gets the current setting of the interrupt priority masking
  704. //! level. The value returned is the priority level such that all interrupts
  705. //! of that priority and lesser priorities are masked. A value of 0 disables
  706. //! priority masking.
  707. //!
  708. //! Smaller numbers correspond to higher interrupt priorities. For example,
  709. //! a priority level mask of 4 allows interrupts of priority level 0-3,
  710. //! and interrupts with a numerical priority of 4 and greater will be blocked.
  711. //!
  712. //! The hardware priority mechanism looks only at the upper N bits of the
  713. //! priority level (where N is 3 for the CC2538 device family), so any
  714. //! prioritization must be performed in those bits.
  715. //!
  716. //! \return Returns the value of the interrupt priority level mask
  717. //
  718. //*****************************************************************************
  719. uint32_t
  720. IntPriorityMaskGet(void)
  721. {
  722. return(CPUbasepriGet());
  723. }
  724. //*****************************************************************************
  725. //
  726. //! Enables the alternate interrupt mapping
  727. //!
  728. //! This function enables the alternate (that is, smaller) interrupt map.
  729. //!
  730. //! \sa See also IntAltMapDisable() and IntAltMapIsEnabled().
  731. //!
  732. //! \return None
  733. //
  734. //*****************************************************************************
  735. void IntAltMapEnable(void)
  736. {
  737. HWREG(SYS_CTRL_I_MAP) |= SYS_CTRL_I_MAP_ALTMAP;
  738. }
  739. //*****************************************************************************
  740. //
  741. //! Disable the alternate interrupt mapping
  742. //!
  743. //! This function disables the alternate (that is, smaller) interrupt map.
  744. //!
  745. //! \sa See also IntAltMapDisable() and IntAltMapIsEnabled().
  746. //!
  747. //! \return None
  748. //
  749. //*****************************************************************************
  750. void IntAltMapDisable(void)
  751. {
  752. HWREG(SYS_CTRL_I_MAP) &= ~SYS_CTRL_I_MAP_ALTMAP;
  753. }
  754. //*****************************************************************************
  755. //
  756. //! Checks to see if the Alternate Interrupt Mapping is in use
  757. //!
  758. //! \sa See also IntAltMapDisable() and IntAltMapIsEnabled().
  759. //!
  760. //! \return Returns \b true if the Alternate Mapping is in use and \b false
  761. //! otherwise.
  762. //
  763. //*****************************************************************************
  764. bool IntAltMapIsEnabled(void)
  765. {
  766. if(HWREG(SYS_CTRL_I_MAP) & SYS_CTRL_I_MAP_ALTMAP)
  767. {
  768. return (true);
  769. }
  770. else
  771. {
  772. return (false);
  773. }
  774. }
  775. //*****************************************************************************
  776. //
  777. // Close the Doxygen group.
  778. //! @}
  779. //
  780. //*****************************************************************************