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