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