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